The little-known translator interface is very similar to the interface used for writing XCMDs and XFCNs, with added provisions for static data.

The translator interface lets you write translators that convert what the user sees in the script editor to whatever form you want.

Typically , the translator interface is used to translate HyperCard's English language scripts into other languages ( French, German, etc ).

But you can use the translator to do much more than substitute one set of words for another.

This appendix shows you how.

_______________

The language in which scripts are displayed in the HyperCard script editor is controlled by the LANGUAGE property. By default, the language is set to English. You can change the value of the language property by using the SET command:

	set the language to 

For this command to work (and not cause an error message), the named script translator must exist as a Macintosh resource of type WTRN (case significant) in the HyperCard application, or Home, or a stackInUse, or a stack. 

You attach the WTRN resource as you would any resource. 

Virtually any number of WTRN script translator resources can exist in a resource file, but only one language can be current at a time. The default language, English, requires no translator resource. 

WTRN stands for "WildTalk Translator".

WildTalk was the code name for HyperTalk during development, and would have been the released name for the language if some company besides Apple hadn't already owned the name.


_______________

HOW A TRANSLATOR WORKS

A WTRN resource is a code segment with no header bytes, like an XCMD or XFCN. It's written in a Macintosh development language such as Pascal, C, etc.

All scripts are always stored on disk in English and executed in English. When the LANGUAGE property is set to a value other than English, HyperCard invokes the appropriate translator whenever it displays or saves a script. 

So the user sees and edits the script in the language of the current translator, but the translator translates scripts back to English before putting it away. And, if the user edits the script again, then the translator translates it again into the current language before displaying it in the script editor window.

So HyperCard can execute any script, regardless of the language in which it was created, and regardless of the language translators available at execution time.

When you use the SET command to change the LANGUAGE property to a non-English value, HyperCard looks for a WTRN resource named the same as the requested value. The following syntax would make HC look for a WTRN resource with the name "German" :

	set the language to German
	
HyperCard uses the standard HyperCard resource hierarchy when it looks for a WTRN resource. The best location for them is in the Home stack or in HyperCard itself.

As long as their names are unique, there can be different translators for the same base language. Each constitutes a different dialect of sorts and has its own language property value. For example, you could have a WTRN named "French1" that does simple word substitutions, plus another WTRN named "French2" that transposes adjectives to appear_after_rather_than_before modified words.

_______________

WHEN A TRANSLATOR IS INVOKED

1.	When the language property is SET to a value other than English :

	HyperCard calls the appropriate script translator, 
	
	which might in turn :
		initialize itself,
		setup translation tables in RAM, 
		and so on.


2.	When the LANGUAGE property is reset from non-English to English :

	HyperCard calls for the departing script translator,
	to deallocate static memory.


3.  When the current language is non-English 
	and the script editor is open :

	HyperCard calls the script translator
	to translate the script from English before displaying it.


4.	When the current language is non-English 
	and the script editor is saved :

	HyperCard calls the script translator
	to translate the displayed script into English
	before writing it to the disk file of the stack.


5.	When the current language is non-English 
	and the user sends a message from the message box :

	HyperCard calls the script translator
	to translate the message into English
	before trying to interpret it
	

6.	When the current language is non-English 
	and the user formats a script in the script editor window
	by pressing the TabKey or the returnKey :

	HyperCard CAN call the script translator
	to indent the displayed script
	rather than doing it itself.
	
	Special note: At initialization time, the translator specifies 
	whether or not it will do its own script formatting (indenting).

_______________

TRANSLATOR INTERFACE DETAILS

Script translators communicate with HyperCard through the translator data block in the same way that external commands and functions communicate with HyperCard through the XCMD data block. The translator data block and its request and result codes have the following form, expressed here in MPW Pascal (*).

DATA FIELDS

When HyperCard invokes a script translator, it passes only one parameter to the translator: a pointer to the translator data block. HyperCard then executes a jump-to-subroutine (JSR) instruction to the translator's entry point, and the translator code segment begin executing. Next, the translator examines the request field of the translator data block to see what HyperCard wants it to do.

REQUEST CODES

HyperCard puts one of the request codes (*SEE constants section of source) into this field to be examined by the translator.

The request code transInit is made when the user executes a SET command for the language specific to the translator. Typically, the translator initializes itself at this time, setting up tables of non-English words to substitute for English words, and so on.

You can allocate these tables in the heap as static data that remains between invocations of the translator.

The ability to maintain static data, plus the fact that HyperCard calls WTRN resources automatically, differentiates WTRN resources from XCMD and XFCN resources.

When you set the language again, HyperCard puts transQuit into the request field. At this time, the translator should deallocate the static data.

HyperCard puts the request transToEng into the request field when the user saves a script after editing it in a non-English language, or sends a non-English message from the msg box.

HyperCard puts the request transFromEng into the request field when the user invokes the script editor to view any script while the language is non-English.

If indentFlag is set in the flags field, HyperCard puts the request transIndent into the request field whenever the user presses the tabKey or the returnKey or opens a script.


RESULT CODES

The translator places one of the result codes (*SEE constants section of source) into the result field when it returns control to HyperCard after executing a request.

If, for example, the translator passes failTrans after HyperCard requests transInit, HyperCard displays the error message "Translator failed to initialize itself", and the language reverts to English.


SRCHANDLE

When HyperCard call the translator to translate a script, either to or from English, it places into this field a handle to a zero-terminated string where the un-translated script currently resides in memory.


DSTHANDLE

When the translator finishes translating a script, either to or from English, it writes the translated script to dstHandle (already allocated by HyperCard).


SELLOC

When an arror occurs in English HyperTalk and you click the script button of the error dialog, HyperCard opens the script editor and places the insertion point as close to the error as it can. It uses the selLoc field to pass an integer that represents the location of the insertion point. 

When the language is non-English, it becomes the translator's responsibility to replace this value with one representing the appropriate point in the translated version of the script. The value of selLoc is an integer representing the number of characters from the beginning of the translated script to the cursor location. If selLoc is 1, then the cursor is after the first character.


FLAGS

If the translator sets bit 0 to 1 (by OR'ing the indentMask onto the flags field), HyperCard doesn't try to indent the translated script when it displays. Rather, the translator should indent the translated script by inserting space characters after each return character, and HyperCard displays the string exactly as received. 

If the flag isn't set to 1, HyperCard attempts to indent the translated script by finding non-English keywords that correlate to the English HyperTalk keywords at the beginning of each line.

The remainder of the flags field is reserved for future use.


RESERVED

This field is reserved for future use.


USERDATA

This array comprises 16 long integer values that the translator can use to maintain data between invocations of the translator.

For example, the French translator example (*) uses 3 elements of this array. 

The first long-integer holds a handle to the string resource containing HyperTalk keywords and their French equivalents.

The second long-integer holds a handle to the hash table the translator builds in memory from the strings so that it can do fast translations.

The third long-integer is interpreted by the translator as 2 integers representing the number of entries in the hash table and its size.

The translator must dispose of its static data when HyperCard calls it with a transQuit request. Otherwise the memory allocated by the translator is tied up until the user quits HyperCard.


_______________

SECONDARY TRANSLATOR USES

As you saw above, the translator was designed to provide a mechanism by which HyperCard scripts can be displayed and created in dialects of HyperTalk other than English.

Most commonly the translator takes text on its way to the script editor, translates it into some appropriate language from English, and then translate it back to English before the script information is sent to the disk.

But the translator interface can transform the information in other ways too. To understand how, think of a translator as a filter that stands between the disk and the script editor. Information is somehow massaged, and finally the information (presumably in some new form) gets sent to th script editor. but how that information is massaged is entirely up to the translator.

The following fully-functional sample (*) shows how to use the translator to do something besides translate from one language to another. It lets you write Pascal-like block comments in a script. You call it with the following statement:

set the language of HyperCard to "BlockComments"

_______________