OvationPro2.56(05-Nov-99)rw,  Pd6HSVnddB $  L L k @0   tn L4  GenericBlack!fWhitefTransparent fRedfGreenfBluefCyan!fMagenta!fYellow !fRegistration Af `.HSVn:Pff.- @?pBDkw-0z)/;Pn WnDSelwynHomerton.BoldHomerton.Medium.ObliqueHomerton.MediumTrinity.MediumCorpus.MediumSidney  Bodytext#/z''-6P33$ Section-Dk.. 70P33, Titlext-Dk]]@n6P33pY SmallTitle/z66?6P333 FunctionName-Dk''-6P33D% MacroName0''-6P33$ Codeext''8.6P33% Listext( /z''-6P33$ nFCaption0@@$6P33  H ,   eg8 /z''-6P33$ NV-Dk.. 70P33, V-Dk]]@n6P33pY 3Q"/z66?6P333 *X ''8.6P33% _h/z''-6P33$ nF_hDW''26P33t' nF_hB?''%6P33 nFW_ 0@@$6P33 Q -Dk''-6P33D% eg8 0''-6P33$ eg8 -Dk''-6P33D% *X   ''8.6P33% N 'L Q>Z S3 S _hNV3Q"VQ *X W_ _hNV3Q"VQ *X W_eg8 L$L  !MainDict!UserDict!Ignore6   @  L A4  tt  L  44   nn7. nn7. l`yy! #0ccMR l X]7:  @ 3QP ?B F- HH   4$ HH Ø 4$ HF  4$ pPp2 L A4  t ttL  44 'nn7. nn7. l`yy! #0ccMR l  X]7tF:tGH ////Word-processing programs have become more powerful over recent years, with many popular ones sporting snazzy new features. Some of these seem good at first but are actually little more than gimmicks. On the other hand, other features might seem boring or not very useful at first but, once you know what they let you do, suddenly become essential. This article introduces the scripting language of Ovation Pro (OvPro), showing how it works and the sort of things you can do with it. What are scripts? Scripts are a feature of many programs and are essentially just a series of instructions to the program. These instructions can be as simple as Type this or can be very complex, involving file handling, styles, effects and just about every aspect of the program in OvPro, even the standard buttons and menus can actually be edited using macros or scripts. A macro is an example of a script that is attached to a button or key. Scripts can also be isolated files or built into extension applets that add completely new features. nOvPro's scripting language is based on C, which makes it slightly odd for those of us who grew up on BASIC, but it is very easy to get the hang of. However, there are a few important points that we need to be aware of. lOAll instructions must end with a semi-colon (;). This is one of the commonest reasons for mistakes; lOUnlike BASIC, variables must be declared before they can be used. SThat is, you cant just write a=32 without first defining what type of variable a is. OvPro supports integers, strings and voids. lOThe mathematical operators are more varied than those in BASIC, which means that they are not always obvious. In particular, the equals sign is used to define variables a=32 but to compare them you use if(a==b). This is another of the commonest mistakes to make in BASIC, you use a single equals sign for both, but you must use two for comparisons in C (and in OvPro scripts). lOUsefully, though, the language offers such short-cuts as !, which means NOT, and ++, which means increment, it will add one to an integer variable. lOCurly brackets {} are used to keep related instructions together, for example the whole macro is enclosed in curly brackets, as in Figure III.  Everyone works a different way, so you may find that my examples are not obviously useful themselves, but they should show you some of the things that are possible and the way the scripting language works. OvPro is undergoing continuous development, and some of these commands may not be documented (or, possibly, implemented) in your copy. It is always best to have the latest version of software, so consult the David Pilling web site.  Why bother? It may seem a lot of bother to write a macro when you can do everything without them. In many cases, this may be true, but if there are operations that you do again and again, it may be worth writing a macro to do them for you. For example, if you write lots of letters to the same person, you might want to write a macro to insert their name at the click of a button, to save yourself typing it. Similarly, if you use special symbols such as frequently, it saves calling up the characters window, selecting the one you want and then closing the window. The reason is always to save yourself trouble. My own interest in macros arose because I edit lots of manuscripts from different authors. To correct their English or style, I need to do the same things over and over again (for example, removing double spaces, correct the spelling of commonly miss-spelled words and so on) and so I gދΉdecided to write some scripts to make my life easier. Over the course of time, I have built up a number of scripts in several programs that I use and some of these are available on my web site (http://fly.to/silent.planet). The simplest scripts The simplest scripts possible in OvPro are those that simply insert text at the caret. However, they are still very useful. These macros can be recorded automatically, as described in the manual: create a new macro and click the Record icon. Any keys you press while the Macro window is open will be recorded in the macro. Alternatively, you can just enter the text into the definition icon. Either way, this allows you to enter text, including special characters such as Return or Tab, in a single action. nFor example, Boo!lM will insert the text Boo! followed by a Return at the caret. The |M is an escape sequence, one of several available to insert characters that would otherwise be difficult to enter. Another possible use of these simple macros is to insert special characters, such as or , without having to call up the Characters window. Thus, creating a macro containing simply as its definition would type this at the caret. The macro can, however, contain any amount of text, up to the limit imposed Figure II: A script to change the font to Trinity, laid out to make it easier to read by the icon that contains the macro (255 characters). Effect changes It is possible to change the effects applied to a section of text, bold or italic for example. A script that does this is shown in Figure I. This also shows why we might want to do it we can change the effect, insert text in that effect and then revert to normal. nFigure I shows this simple script with colour, which makes it easier to work out what is going on, but it doesnt look like this in the macro-editing window, unfortunately. The top line, in green, is a comment, which should be left out of the macro; the beginning of the comment is marked by /* and the end by */. nThe  seteffect command unsurprisingly sets the effects applied to the text at the caret, according to a table that is shown in the manual the 0x at the start of the number indicate that is a hexadecimal value; the  04 is the number itself. This value makes the text italic, which is correct for species name like  Escherichia coli, but you can also apply bold, reverse, underlining and more. After the effect is set, we enter the text and then reset the text effect to normal (the number for this is 01). nThe {NLock} command before the second effect change is needed to flush the effects buffer. If this was not done, only the last  seteffect command would have any effect (no pun intended), meaning that there could only be one change applied to the text in a script. What the {NLock} command actually does is simulate a press of the Num Lock key if you use the keypad, you may need to press it again yourself after using it like this in a script. nYou can see that this script is the same as the above examples but with two new commands added. This is the easiest way to learn to write scripts: break the problem down into smaller steps and learn to do each of those, then build the small steps up into something bigger. Font changes It is also possible to write a script to change the font, useful if you use certain fonts often. There is, in fact, an example of such a script built into OvPro, the button macro  Corpus. This makes it easy to create your own font changes, because you can simply copy this macro and change the font name  Corpus to  Trinity or whatever you prefer (Figure II). nThe top line, in green, is again a comment. The { by itself marks the start of the macro proper. The next two lines declare variables: the first, s, is a string variable but is not set to contain any particular value at this stage; the second, i, is an integer, which is set to zero. cΉ nThe  while statement is very similar to that in BASIC while the expression in brackets is true (that is, non-zero) the rest of the statement enclosed by the curly brackets will be carried out repeatedly the end of the statement is marked by the last semi-colon, which is easy to locate because of the use of curly brackets.  If is also similar to BASIC if the expression in brackets is true, then it will execute the following lines, (again, in curly brackets. nThe details, however, might need some explanation. First, when the function  getfontname is executed, it sets the string s to contain the name of the font whose number is i. Once all the font numbers have been scanned, it returns zero, terminating the  while loop. The integer i is followed by two plus signs. These mean that one is added to the value of i each time the statement is executed, so there is no need to state this elsewhere. nEach time the font name is returned, the script checks whether it is Corpus. If it is, the command  setfont is used to set the font, using the number that returned this name. However, because the integer was incremented during the  while statement, as mentioned above, its value is now one higher than it was. This means that the number passed to  setfont must be i-l. nThus, the first time this while statement is executed, the value of i is zero but is set to 1 immediately after the while statement is executed. This means that if Trinity is font number zero, the  setfont function will be called and we must subtract 1 from it in the If statement to get zero again. lGΉMoving around What do we do if we need to insert text at more than one point in the document? OvPro provides a feature called bookmarks to allow this. These are markers that can be created and set to various locations throughout the document (they are even saved with it). The caret can be moved between these bookmarks, and selections can be set between any two of them. nThere are two important things to remember about bookmarks: they must be defined before they can be used, and they should be deleted as soon as you are finished with them because they remain after the script is finished if you dont. nFigure Ill shows an example script that uses bookmarks to insert brackets around the selected text. First, two integer variables are declared and set to contain the handles of two bookmarks named A and B. The  setbmtozone command sets the bookmarks held in a and b to the start and end of the currently selected text zone. Then, the caret is set to the start of the selected region  (setcarettobm sets the caret to the specified bookmark) and an opening bracket is inserted, followed by the caret being set at the close of the selected region and a closing bracket inserted. Finally, the two bookmarks are deleted. A small problem This script does exactly what we asked of it, but it could be made cleverer. For example, if we have selected whole words which is likely, we will want the opening bracket to be after any spaces before the first word and the closing bracket to be before any spaces after the last word. Fortunately, it is easy to add a quick check step to the macro to make sure that the bookmarks are in the correct place before inserting the text. Figure IV shows the corrected Brackets macro. nThe  bmchar statement returns the ASCII value of the character after the specified bookmark and  bmprevchar returns the value of the character before it. Remember that, in C and OvPro scripts, you need the double equals sign in this position. nAfter this check step,  bmmove moves the bookmark according to the values passed to it. The first value is obviously the bookmark to be moved. The second specifies the direction to be moved (essentially, 0 means backwards and 1 means forwards). The third number specifies how far to move in this case, 0 means one character, although you can also move by word, line and paragraph. nThus, the first while statement checks whether the character after bookmark A is a space (ASCII value 32); if it is, the bookmark is moved forwards one character and the check redone. The second statement checks whether the character before bookmark B is a space and moves the bookmark back one space while it is. After that, the macro carries on as before. rΉhp444 ?HsF-6 ?(F-[ ?сF-x ?F-u ?.F-P ?]F- ?F-m ?hF- ?HF- ?(F-w ?HF- ?vF-C ?ȥF-u ?ԃF-l ?F- ?`2F 7TX ?jF- ?F-] ?hȄF-w ?HF-l ?(&F-x ?UF-B% ?胅F-BW ?ȲF-[ ?F-x ?F-b ?h?F-- ?HnF- ?(F-b ?̆F-R ?F-. ?)F-( ?XF-Vg ?F-_ ?hF-(b ?HF-tf ?(F-fL ?CF-(b ?qF-( ?ȠF-yb-|yb-Hفhybh- -( ?H\F-lyb( -|yb -݁yb -Xyb -pybF -dybu -/L ?hF-UybH - xyb( -tyb1 -Ályb_ -$|ybȎ -^xyb -pD>Hs- D>(-lD>-btD>-xD>.-tD>]-tςaL-b~D>h-ʁtD>H-xہdD>(-|D>H-ςavL-[D>ȥ-\hD>-&#D>-VlD>h2-pςaHaL-ςa(L-]ςaL-]ςaL-vsςaL-NςaKL-*oςazL-lsςahL-BdςaHL-6|ςa(L-l|ςa6L-TςadL-HςaȓL-uςaL- pςaL-ςa` L 7t@ςaXL-wςaL-]ςahL-&ςaHL-tςa(L-JJςaCL- oςaqL-~F@vƒF-_F@VF-zF@6 F-F@OF 7HdF@VF-F@6F-RLF@F-_F@F-pF@BF-|F@qF-8WF@F-hF@vυF-yF@VF-_F@6-F-_F@\F-d?F@F-*=F@ֹF-=F@ӇF-*=F@F-lF@0F-R~F@_F-fF@F-}F@vF-:F@VF-F@6F-,|F@JF-B%|F@xF-wF@֧F-lAF@։F-mF@F-^F@v4F-|F@VcF-F@.F 7lMLF@vʊF-pLF@VF-RF@6(F-hF@WF-"JF@F-uF@ִF-Zq ?B F- ?"~ ?GF-h ?uF-n? ?¤F-[ ?ӆF-I` ?F-j ?b1F-\~ ?B`F-n ?"F-,J ?F-ls ?F- ?F-Nd ?JF-L\ ?yF- ?ZF 70D ?F-`f ?F-H= ?b>F-b ?BmF-w ?F-G ?ˉF- = ?F-4o ?(F- b ?>WF-] ?F-# ?bF-z ?BF-w ?"F-hY ?BF-j ?pF-w ?ŸF-NςaB L-Hςa"<L-WXςahLΉRςa]ML-Pςa|L-hςaL-ĄςaaL-BWςaA L-Ąςa!8L-NdςagL-]ςaL-TYςaL-,|ςa=L-J ςa"L-yςaaQL-&ςaAL-/Pςa!L-XLςaL-hςa} L-@ςa;L-jςajL-ςaL-4=ςaaL-|ςaL-ςa!&L-JςaUL-@|ςaL- oςaL-rςaL-^DςaL-0=|ςaa?L-H~ςaAnL-6ςaL-vs ςaL-lςaL-8Wςa]) L- ςaX L-]ςa L-jςaa L- oςa L-wςa! L-[ςaC L-:ςaq L-lsςa L-xςa L-.Wςa L-0ςaa- L-|ςaA\ L-zςa! L-F@ FΉ^F@F 7O8F@)2F-BWF@ aF-;F@鏃F-R~F@ɾF-F@F-uF@F-RF@iKF-NdF@IzF-+F@)F-tF@ ؄F-UF@F-4F@5F-tF@dF-lsF@F-XdF@i…F-sF@IF-hYF@) F-lF@ OF-LhF@}F-RF@ɬF-`fF@ۆF-@JF@ F-* F@i9F-.F@IhF-lF@ŖF-2qF@ ƇF-8F@F-b2F@#F-\~F@RF-wF@%F-:d F@iF-uF@I߈F-8WF@)F-n?F@ =F-؄F@kF- oF@ɚF-&8F@ɉF-F@F 7lPF@0F-0F@_F-'F@F-F?F@iF-wF@IF-]F@)F-NdF@ JF-RF@xF-^F@ɧF- o ?B F-T ?"F-ʄ ?&F- ?bUF-݁l ?ރF-y  ?"F-h ?F-R~ ?F-R ?^?F-ʄ ?nF-T ?F-u ?b̂F- ?BF-y ?"*F-B%| ?YF-_ ?⇃F- ?¶F-8W ?F-4 ?F-hY ?bCF-u ?BrF-8W ?"F-Ήcҟv> _I ^  #3  Pt X]7de,f d /* Trinity */ { string s; int i=0; while(getfntname(i++,s)) { if(s=="Trinity") { setfont(i-1); } } }  Figure II: A script to change the font to Trinity, laid out to make it easier to read. hhe,,, U 98. H \ U;98.p Uj98.`, U98.( UȀ98.Ih Ug98..  UG&98.L U'U98.PF U98.wD U粁98.PF U98..  U98.p U?98. U*n9$  U9$+  U Hf st Pg Ήދc4X v> _It Ԩ  #3I *׃L X]7hij h /* E.coli */ {seteffect(0x04);} Escherichia coli {NLock} {seteffect(0x01);}  Figure 1: A script to insert text at the caret in italic. 4 i U 98.0 X U;98.L Uj98.wD U98.  UȀ98.L Un98. U&9$ e  UK9$0G $Hj  sutJ(k {filename} P{pagenumber} {datetime}-iKZ l yΉGcv> _I   #3$ zD t X]7mmn,q 00m /* Brackets */ { int a=bmcreate("A"); int b=bmcreate("B"); setbmtozone(a,b); setcarettobm(a); type("("); setcarettobm(b); type(")"); bmdelete(a); bmdelete(b); }  Figure III: A script to insert brackets around the selected textP hn,,, U 98. H \ U;98.p Uj98.0X U98.0X UȀ98.L Uq98.pH UQ&98.0 U1U98.pH U98.0 U98.08 U98.08 U98.p U?98. U4n9$xU  U9$ H UJh\8Hq  s#t r OylΉc&Mv> _I F  #3 $΃t X]7V;stewJseee /* Brackets */ { int a=bmcreate("A"); int b=bmcreate("B"); setbmtozone(a,b); while(bmchar(a)==32) { bmmove(a,1,0); } while(bmprevchar(b)==32) { bmmove(b,0,0); } setcarettobm(a);  type("("); setcarettobm(b); type(")"); bmdelete(a); bmdelete(b); }  Figure IV: A more complete version of the script shown in Figure IIIG t U" 98._ ` U<98. Uj98.p U™98.0X UȀ98.0X U98.L Ub&98.0X UBU98..  U"98.wD U98..  U98.Ih U98..  U?98.wD Un98..  Ub98.pH UB̂98.@ U"98.pH U*98.0 UX98.08 U‡98.08 U98.p U98. U%9$@  U99$R l UDHw % st