Both program and documentation Copyright (C) MML Systems Ltd 11 Sun Street, Finsbury Sq, London EC2M2QD 01 247 0691 Pentlow Mill Cavendish Suffolk. 0787 281072 This software is supplied on the express understanding that the liability of the authors and vendors is strictly limited to the cost of replacement. Under no circumstances does this include any consequential liability of any sort whatsoever. This version of the program and documentation is in the public domain. Under no circumstances may it be sold for profit. Copyright is retained by MML: You are welcome to copy it and give it to your friends. You are not, however, allowed to sell it. 0.1 Preface Scrivener was developed as an exercise in creative programming, a training experience for a novice programmer at MML, and as a rest from writing a particularly long and tedious program for another company. We did, however, seek to cover our expenses with it. To start with, we were asked by Amstrad to come up with a program that would do calculations on ordinary text files. Neither Locoscript nor NewWord 2 can do calculations, and so it seemed a good idea to write a utility to do so. We discussed the various ways that the program might work, and discovered why it was that no one had previously thought of such a simple program. Essentially, we thought, it would be an easy and quick program to write; if something needed to be calculated, the program would substitute the answer for the expression. How, then does one tell the program what needs to be calculated? one might, perfectly reasonably, want expressions in the text that should be left as they are, so one cannot assume that every number or formula should be evaluated. We decided that the user should delimit, by double square brackets, the expressions that they wanted calculated. We chose double square brackets simply because they do not normally occur in text. If, for example, one had the line:- the answer to the expression (3+7+8)/6 is [[(3+7+8)/6 ]] the first expression, (3+7+8)/6, would be ignored, but the second one, between the angle brackets, would be changed into the answer. simple. There is, however, a real world out there. When we asked real people whether this was what they really wanted, they said no. It was all right up to a point, but then, what about being able to put text into a file too?; what about being able to type in prices as one goes along?; what about having variables?; what about being able to line up the decimal points? how could one add up columns, and calculate averages? should'nt one be able to specify the precision of the answer? We decided to go back to scratch and find some real end users who would need this program. "Oh yes," they would all say with innocent looks, "our requirements are very simple." The more one looked, the more complex they became until the idea of a simple little utility started to look rather sick. There was a land drainage company, for example, who had to prepare estimates based on the materials needed, the plant to be used, and the time the job would take. Each director liked the estimate laid out a different way, and the estimate was much greater in length for more complex jobs where an entire estate needed to be quoted for. Once the estimate was prepared, the result needed to go into a file awaiting an invoice. If the job was accepted by the customer, the invoice had to be prepared from the estimate and the result entered into the ledgers. It seemed like a perfect example of a use for the new package, in that the invoice could be prepared with the text editor, calculated up, and then given a final knock into shape with the text editor once again. It actually stretched the package to its limits and set us thinking that the users actually needed something much more powerful. I looked at various small businesses, and asked them what they required from their computer. "Yes", they said brightly "a nice little program to add up rows and columns; just like a spreadsheet, only without having all those cells. What we want is something like a spreadsheet which will work on plain text from a wordprocessor." Everyone was agreed. they wanted it, and could get nothing like it anywhere. They wanted something flexible and adaptable to all sorts of paperwork that the myriad small businesses require to prepare. Each small business seems to run its business in a unique way, so no program bought 'off the shelf' would do. It needed to be something that could be adapted for applications about which the creator of the program had never even dreamed. It is no use asking an end user to put time and effort into a system if it did not answer all his needs. It had to be flexible enough to cope. We set to work with the new brief, and found ourselves designing and programming a completely new sort of utility. Scrivener is the result. The idea that the computer user has some sort of intelligence is somewhat novel. A program such as Scrivener, the result of several months of labour, struck all the pundits who saw it as being impossibly complex. The software industry originally said the same about DBASEII, possibly the most successful program ever written. Everything we put in the language was there for a reason, but the result required some initial hard work from the user. As far as the microcomputer is concerned, we live in the age of shrink- wrapped convenience software, where adaptability and flexibility is sacrificed for a user-interface that requires little from the user. Our program seemed like something from the bad old days of minis and mainframes. My own experience is that a small business that is determined to make best use of a microcomputer, is prepared to put in a lot of effort if it is convinced that the results will be worthwhile. Motivation is everything. What is more important than a friendly user-interface is a good manual and plenty of examples. We agree that there is room for improvement in Scrivener. Even though we know that we will never profit from it, we are continuing to develop the ideas we had for Scrivener as a sort of hobby, and a second version is planned, that is more intuitive to use and has many more features. We have MSDOS versions of the program, and have started on a new manual. We keep getting ideas, and they give us no peace until we code them up. It is a sort of lunacy, but then, that is what hacking is all about. So what does Scrivener do? We see it as a sort of panacea for small businesses, accountants, engineers and scientists. At its simplest, it will produce letters, memos and documents; hence its name. It will also do more complex calculations that traditionally require a spreadsheet. It will not do interactive financial modelling, where one plays about with figures onscreen and sees the figures change before ones eyes, but for delivery notes, statements, quotations, estimates, acknowlegement slips, form letters and so on it is extraordinarily useful. In the documentation that follows, we use an invoice from a mythical private school as one of the examples of how a Scrivener task is built up. Just as spreadsheets work on models, Scrivener works on tasks, the simplest being a text file with a bit of adding up to do, and the more complex being such things as analysis of variance, corporation tax calculation ,profit and loss accounting, and such esoteric stuff. Unlike a spreadsheet, Scrivener task files are just ordinary text files, and can be created with a text file. We give away a few example tasks, such as a simple cashbook, but these are only to provide insiration and examples. It is up to the individual user to make up the task files to suit his or her own usage. No two people seem to perform even the simplest task such as an invoice in exactly the same way and this is the whole reason for Scrivener. Scrivener allows you to do it your way. What you get when Scrivener finishes its work is a text file that can be used by your favourite text processor such as NewWord to make the final touches to the document. Scrivener tasks are best written in stages. For an accounting function, one starts with a layout that can be taken simply from an accountancy textbook, using symbols and variables to make things clear. An accounting task can be set up to conform closely to the layout with which an accountant is familiar. As long as things calculate correctly, one knows that one is on the right track. (do not forget the double-square brackets!). Then comes the process of refinement. What figures are best entered when the task is calculated up? how should the decimal point be aligned? should entries that calculate to zero be left as zero or be left as blanks? What text is best entered when the task is run? how is it made more flexible? Should entered text overwrite or be inserted? One can go on fiddling with tasks until they conform exactly to what one wants. Be warned, though, a complex and lengthy task takes a long time to process! 1. Introduction. 1.1 What does Scrivener do? SCRIVENER is an extraordinarily useful program, if you are handling text. We are constantly thinking up new uses for the program and use it ourselves in-house. Operating Scrivener is easy. Constructing SCRIVENER files takes patience and some time, but repays effort. Scrivener works with a text file. It can do computation and text substitution on it and producing more text. It can send the processed text to the screen, serial port or printer. Scrivener is designed to deal with repetitive clerical work. It is an aid to a text-editing or wordprocessing program. Scrivener is a program that is designed to make life easier for anyone who has to do calculations, prepare documents or letters, or do a repetitive typing or clerical job for which no program exists. It is useful to be able to do calculations and totalling on simple text files, rather than having to use a special program. Using simple text files means that the user can alter the layout and the details before and after processing it. Scrivener will also produce tabular information just like a spreadsheet, but the spreadsheet size is not limited and the layout is completely under the users control. Unlike a spreadsheet, a Scrivener task can be 'run' like a program, making it easy for anyone to enter variable data into a spreadsheet model, without knowing anything about how to construct a 'task'. Scrivener is good for form letters, diaries, journals, ledgers, cashbooks, statistical computations, reports, form filling, repetitive letters, thankyou letters, text conversion work, financial modelling, accounting work and so on. We keep hearing of new uses, do do not feel restricted by these examples but try out new uses. Scrivener is not a derivative program. We cannot say that it is a macro processor because it does so much more: We cannot say that it is a spreadsheet, because it allows requests for data entry and free-form layout rather than column and row entry: We wrote Scrivener because we had ideas that we wanted to try, and wanted to see where they lead us. It is, perhaps, a new way of approaching clerical tasks on a microcomputer. Scrivener should be particularly useful for the self-employed or small businesses in order to help with the paperwork. 1.2 Using Scrivener To operate Scrivener takes very little practice. You have the choice between two ways of operating Scrivener. Firstly, you can type:- Scrivner input.fil output.fil where input.fil is the text file with the calculation or insertion commands already inserted. If INVOICE is the name of the file that you wish to use, to produce an actual invoice called SMITH.LET, then all you need to do is type:- Scrivner INVOICE SMITH.LET You will probably be prompted for the necessary information to complete the invoice. The second way to use Scrivener is to type Scrivner and the program will prompt for the names of the files. On the distribution disc are a number of sample files to practice with. Once you have gained familiarity with using these files, then try experimenting by making small changes in the files, or using different output destinations. If you type CON: as the output file, then the output just goes to the screen (useful for trial runs). If you type LST: then the output goes straight to the printer. This is the way to use Scrivener simply. 1.3 Creating a new Scrivener file To create new 'task' or 'model' files, particularly if they use the more sophisticated features of the package, takes more time and practice. If you persevere, you will be able to set scrivener up do tasks which can be done by no other program. The tasks can then be run by the way we described in the previous paragraph. You will need a text processing program such as Wordstar, Newword, or Pmate. You can use ED but we do not recommend it. Scrivener files are designed using your wordprocessor. For the time being, lets keep our new 'model' simple. Perhaps you are writing a document on your wordprocessor and find yourself typing a column of figures that you need to add-up. I might look like this. (but is more likely to have text, numbers, or expressions around it):- 4454 4564 8646 5.67 654.78 5.864 68 130.687 In order to tell Scrivener that you want it to work on these particular figures and not something else in the text, you must mark the figures you want processed. Scrivener uses the 'double-square-brackets' delimeters, simply because they do not occur in normal text. (you'll get used to this convention!). We want, in this instance, to add-up this column of figures so we put a 't' (t for total) under the column with the word (or 'symbol') total after it. [[ 4454 ]] [[ 4564 ]] [[ 8646 ]] [[ 5.67 ]] [[ 654.78 ]] [[ 5.863 ]] [[ 68 ]] [[ 130.687 ]] --------- [[t total]] We feed the file through Scrivener with the following result:- 4454 4564 8646 5.67 654.78 5.863 68 130.687 --------- 18529 If you make a mistake, the program may fuss around for a while, in the mistaken impression that you have given it a particularly subtle computation, and then will report an error as soon as it is sure that you have goofed. Instead of numbers in your columns, it might have been 'expressions' such as 78.9867*34.6, sin(576/10.86453), or (7010.207- ((167.17^2)/4))/3. Not only can you do this, but you can also use variables to make your expressions more meaningful. Giving values to expressions is done simply by using the 'equals' sign. eg:- [[vat = 15]]. So far, this is not particularly exciting, but the idea can be extended to incorporate most of the work done by a spreadsheet, and includes several ideas that are not possible on a spreadsheet. Some of the calculation facilities are a joy only to a programmer or mathematician, but are nevertheless essential for certain applications. Expressions use precedence rules but it is always a good idea to use parentheses (brackets) to ensure that Scrivener understands the expression exactly the same way that you do. For example, 5 + 3 / 2 could result in 4 or 6.5, depending whether 5 is added to 3 and then divided by 2, or 3 is divided by 2 and the result added to 5. This ambiguity is easily removed by writing (5 + 3) / 2 or 5 + (3 / 2) depending on what you intended. We will explain more about calculations later. Rest assured that it will do a lot more than the four basic functions! Note that the total at the bottom of the list of figures is requested by a rather terse notation. '[[t total]]'. This is deliberate; it allows the commands to be placed in generally the same area as the number or phrase that is finally put there. It is much easier to envisage and design the final layout if this is the case. You will get used to the terse, 'unfriendly' commands. Essentially Scrivener takes a 'task' file, or model, and produces a new text file that can be used just like any other text file. A 'task' or 'model' file is simply an ordinary text file as would come from a text editor or wordprocessor, that has some commands to Scrivener to do text insertions, substitutions or calculations. It will fill in forms, do complicated calculations, and add up both columns and rows of figures. Once one has constructed a 'task' file, it is simple to use it to generate repeated forms, letter or documents is simple. There is nothing magical about a 'task' file, it is simply an ordinary text file that has something in it that Scrivener can work on. It could be a letter, a chapter of a novel, a dumped page from Prestel, an invoice, or some annual results. Scrivener will not only process numbers, it will also process text. Lets take an example:- Imagine that you wish to quickly produce acknowledgement letters to enquiries. You already have a scrivener task file looking something like this:- #input his name,,What is the enquirer's name? #input His address1,,And the first line of the address? #input His address2,,And the second line of the address? #input His address3,,And the third line of the address? #input His address4,,And the fourth line of the address? #input Date,, What is the date, please? His name MML Systems Ltd, His address1 Pentlow Mill His address2 Cavendish His Address3 Suffolk His Address4 Date Dear His name, Thank you for your enquiry about our program called Scrivener. We enclose details of the package. If you have any questions about the package please do not hesitate to phone me. Should you wish to purchase the product we would be pleased to supply it for a licence fee of #29.95. ex VAT. in one-off quantities. Yours Faithfully A. R. M. Clarke. Do not worry for the time being about the strange lines at the top. If the scrivener task file reproduced above is called ACK.IT then all that one would have to do is to type SCRIVNER ACK.IT LETTER.1 to produce a text file with the completed letter on it. Typing SCRIVNER ACK.IT LST: would send the output straight to the printer. The user would get the prompt What is the enquirer's name? --> And the first line of the address? --> And the second line of the address? --> And the third line of the address? --> And the fourth line of the address? --> what is the date, please? --> When all these questions have been answered, the result might look like the following:- Mr Stephen Lee MML Systems Ltd, The Ship Hotel Pentlow Mill Brightlingsea Cavendish Essex Suffolk 23rd Sept 1985 Dear Mr Stephen Lee, Thank you for your enquiry about our program called Scrivener. We enclose details of the package. If you have any questions about the package please do not hesitate to phone me. Should you wish to purchase the product we would be pleased to supply it for a licence fee of #29.95. ex VAT. in one-off quantities. Yours Faithfully A. R. M. Clarke. Notice that all the mysterious stuff at the top of the task file has gone, and his name and address has been filled-in. The Task file is a text file just like the resulting file. It can be changed at will by anyone, one needs no computer knowledge, just the ability to use a text editor. If you wish to insert more text for all further letters to this model, change the task file to suit, if you wish to make a unique modification to this letter, then, edit the result file (letter.1). If you wish to print it out, read it into your favourite wordprocessor program and use its specialised features. Making a task file. At some point, you will want to make a task file. Let us take another imaginary example. You are the school secretary for a private school who is faced with the daunting task of sending out 200 invoices before the start of every new term. They look something like this:- Dotheboys Hall School Ltd Duncayning Duncayning 3549 Spring Term 1986 Name:- Arthur Megabyte Form 5b -------------------------------------------------------------------------- Fees |180.00 Less 5% for 2nd child | 9.00 |171.00 | Lunches | | Piano | Music Books | Speech Training | Brass | Instrument Hire | Milk | 5.50 Extras | | Surcharge | |------------------- # |176.50 Cheques should be crossed and made payable to Dotheboys Hall School Ltd FEES ARE PAYABLE STRICTLY IN ADVANCE AND MUST BE RECEIVED BY THE FIRST DAY OF THE NEW TERM Next Term Begins ..Tuesday 8th Jan Now the school already has a spreadsheet program on the computer. It is of little use for this task because it is impossible to set up the file to print the invoices in the exact format of the invoices, and anyway, it is complex and slow to use for repetitive jobs. The computer has a good wordprocesser, but it will not do the adding up or work out the percentage discount. What you want to be able to do is to simply 'feed in' the things that change, such as the various charges, the date or the name of the child (we call these 'variables'). So the whole process can be done if we set up a 'model' of how the thing ought to look, into which we can put all the variables, just as if we were filling in a form. We can print it out, adjust the layout, the pitch of the printing, and so on until everyone is happy. We will make up labels for every part of the form that requires an entry. (where, on a printed form, we might put a '.........'). Just to make it a bit clearer, we use the '_' character at the start and end of each label, though this not at all necessary. It might then look like this. Dotheboys Hall School Ltd Duncayning Duncayning 3549 _TERM_ Term _YEAR_ Name:- _THE BOYS NAME_ Form _HIS FORM_ -------------------------------------------------------------------------- Fees |_THE FEES_ Less _DISCOUNT_% for 2nd child |_THE FEES_*(_DISCOUNT_/100) |_THE FEES_-Discount | Lunches | _LUNCHES_ | Piano | _PIANO_ Music Books | _MUSIC BOOKS_ Speech Training | _SPEECH_TRAINING_ Brass | _BRASS_ Instrument Hire | _INSTRUMENT HIRE_ Milk | _MILK_ Extras | _EXTRAS_ | Surcharge | _SURCHARGE_ |------------------- # | _BOTTOM LINE_ Cheques should be crossed and made payable to Dotheboys Hall School Ltd FEES ARE PAYABLE STRICTLY IN ADVANCE AND MUST BE RECEIVED BY THE FIRST DAY OF THE NEW TERM Next Term Begins _WHEN IT BEGINS_ Now, obviously, the column of figures should line up 'right justified', in pounds and pence format. We need _BOTTOM LINE_ to be the sum of the column from ' _THE FEES_ - DISCOUNT' to _SURCHARGE_, and DISCOUNT must be the value of the line above. You will notice that there are some variables that are not much altered. The time and date for the beginning of the term is the same for all two hundred invoices but is different for each term. We wish to alter it occasionally as we use the 'model' invoice. We therefore have one of two alternatives. We can simply not have them as variables at all but alter the 'model' itself each term, or we can, rather more conveniently, 'define' them as having a certain value at the start of the file, and then simply alter the start of the 'model' file every term and not have to search through it for parts needing alteration. Let us now 'define' these variables. (we put a '#' sign in front of the word 'define', to tell Scrivener that it is a special command and not the word 'define' that just so happens to be in the text.) #define _TERM_,,Autumn #define _YEAR_,,1986 #define _WHEN IT BEGINS_,,September 11th 1986. This is asking Scrivener to substitute the phrase 'September 11th 1986.' for the phrase '_WHEN IT BEGINS_', 'Autumn ' for _TERM_, and 1986 for _YEAR_ This way of defining variables is fine for the things which change very rarely, say once each term as in the case of the term start date, the year and when it begins. It means merely that before each new set of invoices is to be sent, you edit these define statements under your word processor and on each new invoice sent out, the appropriate changes will have been made correctly. It would, however, be inconvenient to have to enter your word processor for each invoice. It would be easier if we could make Scrivener accept an input from the keyboard for the things which change such as the boys name, the form and all the costs. In order to do this, we use the '#input' statement. At the beginning of the file we put a number of these statements and prompts, so that on each invoice, the person using Scrivener could type in each variable. The prompts are yours to make up, and can be as long as you like. The #input statements might look something like. #input _THE BOYS NAME_,,Enter the pupil's name #input _HIS FORM_,,What form is he in These two statements will handle the replacement of the boys name and his form, so that every time Scrivener came across _THE BOYS NAME_ in the text, it would substitute whatever you typed at the keyboard. We now need to consider how we are going to get the figures into the invoice. Let us forget, for one moment that there are certain important calculations to do; let us just concentrate on getting the figures in. To obtain all the normal costs we would use the '#input' much as we did with the name and form. So now we have, at the head of the file, all the instructions to Scrivener that are necessary. They might look something like this (though if you are ambitious you can make it much more slick!) #define _TERM_,,Autumn #define _YEAR_,,1986 #define _WHEN IT BEGINS_,,September 11th 1986. #input _THE BOYS NAME_,,Enter the pupil's name #input _HIS FORM_,,What form is he in #input _THE FEES_,,What fees should be paid #input _DISCOUNT_,,What discount (if any) for second child #input _LUNCHES_,,What are the lunch costs #input _PIANO_,,Enter his piano costs #input _MUSIC BOOKS_,,Enter the costs of music books #input _SPEECH_TRAINING_,,Enter the costs of speech training #input _BRASS_,,Enter the brass costs #input _INSTRUMENT HIRE_,,Enter the costs of instrument hire #input _MILK_,,Enter the costs of milk #input _EXTRAS_,,Enter the costs of extras #input _SURCHARGE_,,Enter the surcharge The next problem to tackle is that we have to convince Scrivener to do all the calculations and totalling for us. In order to do this, we must put '[[' and ']]' around any calculations, or numbers that are to be used for calculations. We do this because we need to tell Scrivener to get to work on what is between the delimeters. If Scrivener grasped every expression given to it, then we would not be able to put mathematical expressions into any text. So the main section now looks like:- Dotheboys Hall School Ltd Duncayning Duncayning 3549 _TERM_ Term _YEAR_ Name:- _THE BOYS NAME_ Form _HIS FORM_ -------------------------------------------------------------------------- Fees | [[ _THE FEES_]] discount for 2nd child | [[z -_THE FEES_*(_DISCOUNT_/100)]] | [[t ftotal]] | Lunches | [[ _LUNCHES_]] | Piano | [[ _PIANO_]] Music Books | [[ _MUSIC BOOKS_]] Speech Training | [[ _SPEECH_TRAINING_]] Brass | [[ _BRASS_]] Instrument Hire | [[ _INSTRUMENT HIRE_]] Milk | [[ _MILK_]] Extras | [[ _EXTRAS_]] | Surcharge | [[z _SURCHARGE_]] |------------------- # | [[t total]] Cheques should be crossed and made payable to Dotheboys Hall School Ltd FEES ARE PAYABLE STRICTLY IN ADVANCE AND MUST BE RECEIVED BY THE FIRST DAY OF THE NEW TERM Next Term Begins _WHEN IT BEGINS_ This introduces a few new points. First of all, each calculation inside the brackets has two sections. This is because there are a great number of ways of representing numbers or quantities in commercial or scientific use. You can rely on Scrivener's way of doing it, but you can actually specify other ways that may be more suitable for your application. The first section after the '[[' allows you to specify any special ways that you would like the value put in the file. If you wish to use this facility, it consists of one or more letters followed by a space. It is put before the actual calculation. We need to use only two single-letter commands here, 't' and 'z'. The 't' indicates that we want a total of all the numbers in the same column up to that point. So we use it for totalling the entire column, as well as taking the discount away from the fees. The 'z' indicates that we want the line deleted if the result of the calculation is zero. So if the discount is zero we remove the line completely. Similarly with the surcharge. Well let's try it out. Let us pass the file through Scrivener. This might be the result:- Version 1.0 MML Systems Ltd ***Enter the pupil's name --> Arthur Megabyte What fees should be paid --> 180 What form is he in --> 2BJ What discount for second child --> 9 Enter the lunch costs --> 56 Enter piano costs --> 0 Enter the costs of music books --> 0 Enter the costs of speech training --> 70 Enter the brass costs --> 0 Enter the costs of instrument hire --> 0 Enter the cost for milk --> 5.5 Enter the surcharge --> 0 giving the appropriate reply to prompts, results in:- Dotheboys Hall School Ltd Duncayning Duncayning 3549 Autumn Term 1986 Name:- Arthur Megabyte Form 2BJ -------------------------------------------------------------------------- Fees | 180 discount for 2nd child | -9 | 171 | Lunches | 56 | Piano | 0 Music Books | 0 Speech Training | 70 Brass | 0 Instrument Hire | 0 Milk | 5.5 Extras | 0 | |------------------- # | 176.5 Cheques should be crossed and made payable to Dotheboys Hall School Ltd FEES ARE PAYABLE STRICTLY IN ADVANCE AND MUST BE RECEIVED BY THE FIRST DAY OF THE NEW TERM Next Term Begins September 11th 1986. That shows that we have at least got the logic right. When preparing a model like this it is always best to make sure that your logic and mathematics are correct, before improving the appearence of the output. Add new ideas and features in easy stages, testing things out as you go. A moments inspection of the result of the 'model' so far will convince us that there is some work still to do to get what we want. For a start, the columns are not lined up accurately. This requires that we tell Scrivener something about the way we want the numbers formatted. This is done by using the single letter 'f' command (meaning format). This has three parts to it; the field width, the number of decimal places to print to and whether or not to include trailing zeros. In this case the field width would be about 8 characters, we want 2 places of decimals and we want trailing zeroes kept. So at the beginning of the file we put [[def 8.2t]] This mysterious legend tells Scrivener what we want to do. Although its meaning is rather opaque to us, It is very easy for the program to understand. Long meaningful commands and labels are easier to learn, but they spoil the layout through taking too much space. The '[[' at the start gives Scrivener a nudge and signals that something significant is following. What actually follows is the optional section that we have mentioned. The 'd' (Delete line) at the beginning means that the line should be deleted, and not put in the final output. The 'e' that follows commands Scrivener not to attempt to evaluate the second section, which, in fact, is left blank. What follows is the 'f' command (Format) which, in the '8.2t', is asking Scrivener to allow eight spaces for the column, represent the number to two decimal places, and put trailing zeros in the number. This command is so often used in commercial work that it can be copied without spending too much effort into understanding the whys and wherefores. It also looks out of place to have zeroes for all the sections which do not apply to a particular child. We could use the 'delete if zero' command to delete the entire line if it is unused, but as the headmaster insists that the new Scrivener invoice should conform to the old handwritten ones (so as not to confuse the parents) we choose, instead, to use the 'b' command to blank out the zeroes. The choice is in our control, by using the first section after the '[['. So we now have a usable file, though there is still much we can do to improve it. The source should now be:- #define _TERM_,,Autumn #define _YEAR_,,1986 #define _WHEN IT BEGINS_,,September 11th 1986. #input _THE BOYS NAME_,,Enter the pupil's name #input _HIS FORM_,,What form is he in #input _THE FEES_,,What fees should be paid #input _DISCOUNT_,,What discount for second child #input _LUNCHES_,,Enter the lunch costs #input _PIANO_,,Enter piano costs #input _MUSIC BOOKS_,,Enter the costs of music books #input _SPEECH_TRAINING_,,Enter the costs of speech training #input _BRASS_,,Enter the brass costs #input _INSTRUMENT HIRE_,,Enter the costs of instrument hire #input _MILK_,,Enter the costs of milk #input _EXTRAS_,,Enter the costs of extras #input _SURCHARGE_,,Enter the surcharge [[def 8.2t]] Dotheboys Hall School Ltd Duncayning Duncayning 3549 _TERM_ Term _YEAR_ Name:- _THE BOYS NAME_ Form _HIS FORM_ -------------------------------------------------------------------------- Fees | [[ _THE FEES_]] discount for 2nd child | [[ -_THE FEES_*(_DISCOUNT_/100)]] |----------------------- | Total fees | [[t ftotal]] | Lunches | [[b _LUNCHES_]] | Piano | [[b _PIANO_]] Music Books | [[b _MUSIC BOOKS_]] Speech Training | [[b _SPEECH_TRAINING_]] Brass | [[b _BRASS_]] Instrument Hire | [[b _INSTRUMENT HIRE_]] Milk | [[b _MILK_]] Extras | [[b _EXTRAS_]] | Surcharge | [[b _SURCHARGE_]] |---------------------- # | [[t total]] Cheques should be crossed and made payable to Dotheboys Hall School Ltd FEES ARE PAYABLE STRICTLY IN ADVANCE AND MUST BE RECEIVED BY THE FIRST DAY OF THE NEW TERM Next Term Begins _WHEN IT BEGINS_ and we get an output file something like:- Dotheboys Hall School Ltd Duncayning Duncayning 3549 Autumn Term 1986 Name:- Arthur Megabyte Form 2BJ -------------------------------------------------------------------------- Fees | 180.00 discount for 2nd child | -9.00 |----------------------- | Total fees | 171.00 | Lunches | | Piano | Music Books | Speech Training | Brass | Instrument Hire | Milk | 5.50 Extras | | Surcharge | |---------------------- # | 176.50 Cheques should be crossed and made payable to Dotheboys Hall School Ltd FEES ARE PAYABLE STRICTLY IN ADVANCE AND MUST BE RECEIVED BY THE FIRST DAY OF THE NEW TERM Next Term Begins September 11th 1986. Note that all the '#define' and '#input' commands have been removed automatically by Scrivener, all the numbers are now in a neat column and all the zeroes have been blanked out. If the headmaster, who never liked those d**ned computers anyway, insists on a change in the format on seeing the output, then you can smile sweetly and merely change the format command ( that was the one looking like '[[def 8.2t]]' ). We now have something workable to produce all those invoices neatly and conveniently. However, there are many ways of improving the process. We have no facilities for adding other chargeable items that may only apply to one or two children in the school. (Those Ballet lessons for Basil, for example). We may also want to print out the total for each child or 'post' the results of the invioce into another file which can, in turn, be passed through Scrivener.. #announce ^j^j^j #define _TERM_,,Autumn #define _YEAR_,,1986 #define _WHEN IT BEGINS_,,September 11th 1986. #input _THE BOYS NAME_,,Enter the pupil's name #input _HIS FORM_,,What form is he in #input _THE FEES_,,What fees should be paid #input _DISCOUNT_,,What discount for second child #input _LUNCHES_,,Enter the lunch costs #input _PIANO_,,Enter piano costs #input _MUSIC BOOKS_,,Enter the costs of music books #input _SPEECH_TRAINING_,,Enter the costs of speech training #input _BRASS_,,Enter the brass costs #input _INSTRUMENT HIRE_,,Enter the costs of instrument hire #input _SURCHARGE_,,Enter the surcharge #input _HOW MANY_,,Enter the number of extras [[def 8.2t]] Dotheboys Hall School Ltd Duncayning Duncayning 3549 _TERM_ Term _YEAR_ Name:- _THE BOYS NAME_ Form _HIS FORM_ ---------------------------------------------------------------- Fees | [[ _THE FEES_]] discount for 2nd child | [[z -_THE FEES_*(_DISCOUNT_/100)]] |------------- | Total fees | [[t ftotal]] | Lunches | [[b _LUNCHES_]] | Piano | [[b _PIANO_]] Music Books | [[b _MUSIC BOOKS_]] | Speech Training | [[b _SPEECH_TRAINING_]] | Brass | [[b _BRASS_]] Instrument Hire | [[b _INSTRUMENT HIRE_]] | Extras:- | [[sz _HOW MANY_]] #repeat #include school.inc,,_HOW MANY_ | Surcharge | [[b _SURCHARGE_]] |------------- | # | [[t total]] ============= [[dp Total of _THE BOYS NAME_ is ,,total,,]] [[dm totals]] [[dp [[,,total,,^]^] _THE BOYS NAME_>] [[dm con:>] Cheques should be crossed and made payable to Dotheboys Hall School Ltd FEES ARE PAYABLE STRICTLY IN ADVANCE AND MUST BE RECEIVED BY THE FIRST DAY OF THE NEW TERM Next Term Begins _WHEN IT BEGINS_ The .pa at the end of the file is only applicable if you are using Scrivener with NEWWord or WordStar. It would produce each new invoice on a new sheet. The #repeat function includes the file school.inc: #input _DESCRIPTION_,,Enter the description #input _COST_,,Enter the cost #overtype _DESCRIPTION_ | [[b _COST_]] #insert HOW MANY times. The dp command prints out the total to the screen.The dm command will redirect the print commands that follow it to the file name given, in this case 'totals'. This will allow a file of the total invoice returns expected to be built up. This can then, with minor changes, be passed through Scrivener, to inform the headmaster exactly how much he is skinning the parents for. This would produce output like:- Dotheboys Hall School Ltd Duncayning Duncayning 3549 Autumn Term 1986 Name:- Arthur Megabyte Form 2BJ ---------------------------------------------------------------- Fees | 180.00 |------------- | Total fees | 180.00 | Lunches | | Piano | Music Books | | Speech Training | 17.50 | Brass | Instrument Hire | | Extras:- | Milk | 5.50 | Surcharge | 12.00 |------------- | # | 216.00 ============= Cheques should be crossed and made payable to Dotheboys Hall School Ltd FEES ARE PAYABLE STRICTLY IN ADVANCE AND MUST BE RECEIVED BY THE FIRST DAY OF THE NEW TERM Next Term Begins September 11th 1986. Obviously, a fair amount of work has gone into getting the invoice just right. However, it can now be used over and over again. It can be modified over a period of time in the light of changing needs, and so on. Once the work is done, the 'task file' is always there. If you are using Scrivener, it pays to build up a library of task files to suit the work you have to do. Using or altering an existing task file is very easy and takes little time. Making a new task requires a bit of patience. Look for an example that approximates to what you want and alter it to suit. Add and test out new features one by one. Scrivener is not dressed-up with gimmicks, but rewards a little bit of time to master the conventions of using it. Imagine that we have a simple calculation to do, and for some reason, wanted to do it on the computer rather than the pocket calculator. The calculation is to calculate the depreciation of a piece of machinery :- #input _COST_,,The cost of the asset was #input _LIFE_,,Enter the estimated lifetime of the asset #input _EDV_,,Enter the estimated disposal value of the asset [[d of=(_EDV_/_COST_)]] [[d root=of^(1/_LIFE_)]] [[d rate=100-(100*(root))]] [[def 8.3]] [[dp the rate of depreciation of the asset is ,,rate,,%]] This takes the user input for cost,life and estimated disposal value of the machinery and calculates the rate according to the equation rate=100-(100*(estimated disposal value/cost)^(1/life)) (a power of 1/n is equivalent to the nth root). Using the Scrivener 'm' statement to mail the print statements to an output file, it would be possible to build up a large number of depreciation of assets, which could further be included in other calculations with or without uing Scrivener. It is very easy to customise such a task file to your own taste, using the flexibility of your own text editor. For example, you may wish to present to the managing director of a firm, a detailed list of all the depreciation rates of all his equipment. This can be done by simple changes to the above file :- #input _NAME_,,Enter the name of the asset (max 20 letters) #input _COST_,,The cost of the asset was #input _LIFE_,,Enter the estimated lifetime of the asset #input _EDV_,,Enter the estimated disposal value of the asset [[def 8.6]] [[d of=(_EDV_/_COST_)]] [[d root=of^(1/_LIFE_)]] [[d rate=100-(100*(root))]] [[def 8.3]] #overtype [[dm deprec.out]] [[dp the rate of depreciation of the _NAME_ is ,,rate,,^j^j^m]] #insert this will produce an output to the file deprec.out which looks like:- the rate of depreciation of the Mole Drainer is 33.126 the rate of depreciation of the Trencher is 20.63 the rate of depreciation of the Digger is 16.375 the rate of depreciation of the Trailer is 29.289 the rate of depreciation of the Tractor is 33.167 for the appropriate input. The file can be made even flashier to produce a file which can again be passed through Scrivener to work out average depreciation, total loss on assets for one year and so on, as you become more adept at Scrivener's powers and uses. 1.4 Using the calculator. So far, we have not dwelt at length on the calculator functions. 'Expressions' can range from the simple:- [[ 1 ]] to the complex, involving assignments, operators, operations and functions. These can be written just as if they were included in a BASIC program. Naturally, the left hand side of the expression, if it exists, can only be a variable, (not another expression). so, [[ vat*10=150 ]] is wrong whereas:- [[ vat = 150/10 ]] is all right. are in two parts, though the first is only optional. In order to be able to specify exactly how you wish the result, you can specify a series of characters, each of which have certain significance. The second part of any expression you want Scrivener to evaluate is the calculation itself. This can be anything from a simple addition to hyperbolic trigonometrical functions. It may include extensive use of variables. Variables may be a maximum of eight letters in length and can be assigned to, or used in a calculation after they have been assigned. When you make an assignment to a variable, and it does not already exist, Scrivener decides that you want to create it with an initial value equivalent to the value you assign to it. In this way, you can use variables in your computations, to make them more easily readable. All the normal mathematical operators are allowed. We will need to wait until later in the documentation for the full details on the calculator and the functions that provide boolean and trigonometric functions. The mathematical expressions follow the standard conventions and are readily grasped by anyone familiar with elementary mathematics. A useful way to practice, or to key-in simple expressions is to use the simple two-line program:- #input mac_calc,,^j^j^jWhat do you wish calculated [[dp mac_calc = ,,mac_calc,, ]] If you run this and answer with a variety of expressions you will soon become familiar with the way SCRIVENER does calculations. 2. How Scrivener works. Scrivener is basically a macro translator and multiple pass calculator, with added unusual macro functions to improve its ease of use and flexibility. It can accept parameters to be used in macros and can also accept input from the keyboard (or a redirection file). It can also append lines of output to the end of other files. The macro pass can be used to great effect, in manipulating calculations, producing standard letters, doing mail shots as well as complex text manipulation. The multiple pass calculator allows delimited calculations to be computed and can include forward references to variables. It also includes many logical functions as well as a full range of scientific ones. It also includes column and row totals, a user stack with average, sum and lookup functions. Normal operator precedence is assumed by the calculator and unusual forms of calculations can assign variables inside calculations. Unlike spreadsheets, Scrivener does not require calculations to be placed in specific places, nor does it assume standard, meaningless variable names such as H35, but allows more flexible use, with variable names such as cost,total etc. 2.1 Scrivener in operation. Scrivener takes an input file name, either from the command line or via a prompt as well as an output file name in the same way. The command line may also contain one other parameter, a -m mail merge option. The input file is opened as is a temporary file, called 'temp.fil'. On the first pass, each line of the input file is read, all the macro translations are made, and the result of each line is output to the temporary file. Hereafter, the input file remains untouched and is not used. On the next pass, each line of the temporary file is read in and all the calculations are done, this pass is repeated until either all the calculations have successfully been completed, or five such passes have been made. The final pass opens the output file for appending (or creates it if it does not already exist). It then procedes much as the other passes, taking each line from the temporary file, and evaluating the necessary calculations. All the appropriate formatting of results is done, and the final polished line is output. All lines set for deletion are deleted at this point. If, on the final pass, some calculations are not completed, due to errors in the input file, mathematical errors or undefined symbols, the result is given as zero. In most cases, Scrivener will announce errors as they occur, though in some cases, due to its flexible syntax, will make sense of some calculations with missing brackets etc., and so may not gice an error where one is expected. 3. Macros. The macro translator is one of the more powerful aspects of the Scrivener package and can be used for everything from simple search and replace functions, to complex personalization of letters and mail shots. Generally, the functions are variations of the 'define' function and can be treated similarly. Essentially the 'define' function allows a piece of text such as a word or phrase to be substituted for another. Each definition consists of two parts, the first is the part by which it is recognized (the name), the last is the part which will replace this (the definition). The two parts are separated by a double comma (,,). Before each definition is assigned it is searched to see if it contains a previously defined macro name. If any are found they are replaced. Either the name or the definition may contain control characters signified by a ^. These are generally specific to the machine being used, but it is possible, for example, to replace all the tabs in a file with a single space by including #define ^I,, at the files beginning. A name may be redefined at any time by just defining it again via any of the defining macro commands. All macro commands are deleted in the final output file. The commands available to the macro translator are :- DEFINE #define name,,definition This is the easiest form of the macro translator. It simply will replace all appearances of name by definition. This definition may include anything up to nine parameters given after name in the text. For example:- #define cust_name,,Customer Name will replace cust_name in the text which follows the definition by Customer name. #define cost_of_item,,The $1 costs #$2 will find all cost_of_items in the text and will replace them with the text and parameters 1 and 2 (shown by the dollar) imbedded in the appropriate point. So if cost_of_item [bag of cement,,3.80] occurs in the text following the definition, it will be replaced by The bag of cement costs #3.80. The parameters are recognized in the definition by the dollar sign (note that a single dollar symbol may be obtained by a $$) and all parameters in the text must be enclosed in square brackets. It is possible to use parameters in the definition in a different order than they occur after the name. If we redefine cost_of_item by, later in the text, typing:- #define cost_of_item,,The #$2 you paid was for $1 then the occurrence of cost_of_item [3 yards of piping,,2.80] will, after this definition, be replaced by the #2.80 you paid was for 3 yards of piping OVERTYPE #overtype After this function appears in the text, and until a #insert appears, all replacements made are either padded out with enough spaces to fill the area occupied by the name, or they overtype any text in front of them if necessary. This is particularly useful in setting up columns of figures with macros in them. Problems can occur if macros overtype a single tab character. This causes columns to 'pull back' towards the left. The safest way to avoid this is to ensure that, where macro replacements are going to be made, columns are padded out with spaces and not tabs. INSERT #insert After this appears in the text, all replacements are inserted into the space previously used by the name, no text is overwritten and no spaces added as with overtype. This is the default value, at the beginning of the file. INPUT #input name,,prompt[,,definition] This function will stop processing of Scrivener and display a prompt to the screen (or outward redirection file) and will wait for an input from the keyboard (or the inward redirection file). It will then create a definition recognized by name and consisting either of definition (which may or may not include the input in it) or by default, just the input. For example:- #input inv_no,,Please enter the invoice number will print Please enter the invoice number --> on the screen and will then wait for a user input (or that from a redirection file). Thereafter, it will replace all occurrences of inv_no by the input given at this prompt. #input inv_no,,Please enter the invoice number,,Invoice number is $I will print Please enter the invoice number --> again and will again accept an input. This time it will replace the $I in the definition by the input, and will define inv_no as that resultant definition. So if the input was 67245 all following occurrences of inv_no will be replaced by Invoice number is 67245 throughout the text file. This form of input is the same as doing #input mac_inv,,Please enter the invoice number #define inv_no,,Invoice number is mac_inv DEFAULT #default default_value This function is used to provide a default for the input statement, so that, if, at run time, the user merely types return to an input request, sensible values can be obtained. For example:- #input _PRICE_,,Enter the price total cost [[ _PRICE_ * 1.15]] would give an error message if no input is given, whilst #default 0 #input _PRICE_,,Enter the price total cost [[ _PRICE_ * 1.15]] would give no error message, and the default zero would be used if no input was given, INCLUDE #include filename This function can be used to include a separate file inside the original one. This file can consist of any text, more macro definitions, Scrivener calculations (though not requests for totals or clear totals) or even other includes. Nesting 'include' statements may cause problems in large files or if they are nested too deeply, as it can cause interference with the stack. In general try not to nest include requests more than twice or three times. #include extra.fil found in a source text file, will ask Scrivener to open the file called "extra.fil" and will then take lines from that file as if they were lines from the original file. So if extra.fil contains #input mac_date,,Enter the date,,today's date:- Company X Ltd Our Premises The Street The Town mac_date upon entering '29th August, 1985.', it will insert into the file Company X Ltd Our Premises The Street The Town 29th August, 1985. ANNOUNCE #announce output line This function allows the source text file to output something to the screen. This may include control characters (as may the input function in its prompt). For example:- #announce ^m^j^jThis is the program beginning will print on the screen two new lines (the control m is signified by the ^m - a ^ is obtained by ^^ and a control^ is signified by a ^~ ). It is important to note that the announce line is passed through the replacement routine so macros may be included in it. #define current_price_of_cheese,,98p per lb #announce The cost of cheese is current_price_of_cheese. will print The cost of cheese is 98p per lb. on the screen. RANDOM #random name,,phrase[,,phrase[,,phrase .... ]] This unusual function can be used to "personalize" letters by using random synonymous phrases. Up to six phrases can be chosen from by the random function. For example:- #random thank_phrase,,Thank you for,,Many thanks for,,It was kind of you to send in the text will assign one of the three phrases following it as the definition of thank_phrase, so that when thank_phrase the parcel. occurs in the text it will be replaced by either Thank you for the parcel. or Many thanks for the parcel. or It was kind of you to send the parcel. As this function merely produces a random definition within the limits you set it, it is identical to the define function in use and can contain parameters etc. (cf define). REPEAT #repeat line,,no of times This function can be used to repeat one line many times in the output file (or many lines - see techniques). A line cannot be repeated more than 100 times (if you try, only a maximum of 100 will be replaced). #repeat #include another.fil,,4 will include (cf include function) the file "another.fil" four times, doing all the macro functions and replacements within that file as it inserts it. 5. Calculator. The calculator is a full function multi-pass calculator, which allows the assignments of variables, includes a stack,last answer recall,simple lookups, boolean and bitwise logic as well as a conditional. All calculator functions are performed after the macro pass, so, though Scrivener's macro ability can be used powerfully to alter calculations, the reverse is not true. Some additional commands have been added to the calculator to go some way to compensate for this. Full formatting of numbers is allowed, deletion of working is possible and a 'delete if zero' command is available. The calculator recognises all its calculations by delimiters which consist of '[[' (open square brackets and less than) at the beginning and ']]' (greater than and close square brackets) at the end. The calculation itself is broken into two parts, a header and a body. The header controls exactly how Scrivener handles the calculation, and what it does with the result, whilst the body handles the mathematics and expressions. Header commands consist of a single letter and can be mixed to create other effects. The two parts of the section must be separates by a space (even if either of them are actually nothing). By default (ie if you type a space then an expression, after the opening brackets ), Scrivener assumes that the expression is to be calculated and the result is to replace the expression in the text (padded by spaces to make sure columns don't go out of alignment). This default can be altered or added to by the following set of commands:- D - Delete line The d command can be used to delete the line on which appears. It is normally used to remove side working (against any mathematics teacher's advice). It is also useful for squeezing large expressions into small places (see techniques). L - Line total The l command is to allow you to assign the total of all the calculations to a variable. If [[ x = 10]] [[ y = 19]] [[ x * y]] [[l var1]] appeared in the text, Scrivener would assign var1 the value of x+y+xy ie 219 and on output would produce 10 19 190 219 in the output file. It is possible to include more than one line total in a line, each of which would give a total up to that point, e.g. [[ x = 10]] [[ y = 19]] [[l var1]] [[ x * y]] [[l var2]] would give an output 10 19 29 190 219 (note that the l command automatically prevents addition of its result to the line total - i.e. in the above example var1 does not get added to var2). F - Format This command allows the user to format numbers, declaring the number of decimal places of accuracy, minimum field width and whether or not to remove trailing zeroes. The format of this command is [[f A.BT]] where A is the minimum field width,B is the number of decimal places the numbers are to be taken to and T is a flag which if set means that trailing zeroes (after the decimal point) are to be included (otherwise they are removed). If the field width is larger than the length of the resultant number then it is right justified by adding leading spaces ( a minus sign will left justify the number ). So, if [[f 4.2t]] [[ x=9]] [[ y=10.5]] appeared in the source 9.00 10.50 would be output (note that the format command is automatically replaced with spaces in the output), whereas if [[f 8.2]] [[ x=9]] [[ y=10.5]] occurs 9 10.5 would be output, the trailing spaces having been removed (and the trailing decimal point in the case of x=9). E - do not Express This is a useful addition to the Scrivener set to add a comment beside some working in the source file which will be replaced by spaces in the final output file. For example:- [[ x=10]] [[e this comment could tell you what x is]] would give 10 as its result, the comment having been replaced by spaces for the output. The use of comments to explain in the source exactly what is going on is very useful (especially if you - or someone else - tries to understand it months or years after it was written). A - do not Add to totals This function prevents the result of the calculation being added to both line and column totals. This is useful if side calculations are not required to be added and to allow calculations in columns where column totals are requested. If [[ x=9]] [[ y=13]] [[a z=15]] [[l atotal]] [[ z2=15]] [[t total2]] will result in 9 13 15 22 15 15 instead of 9 13 15 37 15 30 if the a command had been missing ( and the 15 been added to both the line and column total). T - column Total This powerful feature of Scrivener can be used to sum all the results of the calculations in a column. The t command must be applied to a variable which will hold the sum of the column, so the body of this command must be the name of the variable you want this assigned to. The column is defined by the open square bracket of the delimiter i.e. all the calculations whose open +brackets are in the same column as those of the total request. E.g. [[f 8.2]] cost of pipes [[ 12 ]] cost of taps [[ 15 ]] cost of basins [[ 756 ]] total [[t total ]] vat [[ vat=total*0.15]] final total [[t ftotal]] will result in cost of pipes 12 cost of taps 15 cost of basins 756 total 783 vat 117.45 final total 900.45 Note that the results of total requests are not themselves added to totals further down the column. C - Clear total This command can be used to reset the column total, so two separate column totals can be done one under the other in the same column (cf T - column total command). For example [[f 8.2]] 9 bags of cement [[ 9*3.20]] 3 tons gravel [[ 3*8.70]] hire of lorry [[ 10.80]] sub-total [[t total]] [[ce ]] 3 days labour [[ 3*15.00]] 4 hours overtime [[ 4*3.50]] labour total [[t ltotal]] total cost [[ total+ltotal]] would give 9 bags of cement 28.8 3 tons gravel 26.1 hire of lorry 10.8 sub-total 65.7 3 days labour 45 4 hours overtime 14 labour total 59 total cost 124.7 Z - delete line if Zero This conditional command is useful for removing redundant phrases from text calculations, for instance to remove lines referring to discount if the discount is zero can be removed. E.g. Discount given [[z dis]] will remove the entire line if the variable 'dis' is zero, otherwise it will leave it and replace the command by the value of dis. S - replace with Spaces Similarly to delete line, this command will replace the section that it is in by an appropriate number of spaces - this would be used to remove side working. For example:= [[ x=10]] [[s y=19]] [[ x*y]] will give 10 190 the middle command having been replaced with spaces, but having actually been calculated and the assignment made. P - Print This command allows the user to output to the screen (or redirection file) some information which may include the contents of variables. Note that all print commands are executed after all the macro announce commands (cf #announce). This command produces no output to the output file, but only to the screen or redirection file. Any variables or calculations must be enclosed by double commas to separate direct screen output from that which needs to be calculated. [[ x=9]] [[ y=15]] [[p The product of x and y is ,,x*y,, the sum is ,,x+y,,]] would result in The product of x and y is 135 the sum is 24 being output on the screen with an output file of 9 15 being produced with the print statement having been replaced with spaces - if dp is used as an alternative the entire line would be removed. M - Mail to file Using this function, it is possible to redirect the output of a print statement (cf p - print) to append to a file (or create it if it does not already exist). This is useful to create files of invoice totals, which can, later, be used for cash management etc. and can even be passed through Scrivener (using minor changes) for further calculations. For example:- [[m output.fil]] [[p This result should go to "output.fil" ]] [[m CON:]] [[p and this should go to the screen]] would output the result of the first print statement to the file called 'output.fil' and the second to the screen (con: meaning console - we could use lst: for list device or pun: for RS232 out). It is still possible to write the results of calculations using the print statement, merely that the result is appended to a file rather than cast to the screen. O - Overtype This function prevents Scrivener from padding out the answer with spaces so that it fills the same space as the original source. This it does by default, in order that columns will not be destroyed as answers of varying length are output. In text however, it may be necessary for numbers to appear "naturally" in a line. If, for example [[def 4.2t]] The #[[ 3*7.5]] you paid was received with thanks were to appear, Scrivener would interpret this as The #22.50 you paid was received with thanks whereas, if [[def 4.2t]] The #[[o 3*7.5]] you paid was received with thanks were in the file, it would be interpreted as The #22.50 you paid was received with thanks B - Blank if zero This function will replace a result with spaces, if it is zero. It is similar, and has similar uses, to the z, delete if zero, command. So Discount [[b dis]] will have the result Discount if dis is zero and Discount 9.85 or similar if dis is non zero. The second part of any expression you want Scrivener to evaluate is the calculation itself. This can be anything from a simple addition to hyperbolic trigonometrical functions. It may include extensive use of variables. Variables may be a maximum of eight letters in length and can be assigned to, or used in a calculation after they have been assigned. The simple operators used by Scrivener are + addition - subtraction * multiplication / division \ modulus ^ to the power of | bitwise or & bitwise and ' bitwise exclusive or these have precedence as follows -> -> -> Precedence increasing -> -> -> Precedence 0 1 2 3 4 ------------------------------------------------------- | + * ^ () & - / ' \ this conforms to the precedence given by PL/I The calculator also has built in function which include some boolean functions such as if, greater etc. The full range of functions are:- sin(x) the sine of x radians cos(x) the cosine of x radians tan(x) the tangent of x radians log(x) the log (to the base 10) of x ln(x) the natural log (to the base e) of x abs(x) the absolute value of x sqrt(x) the square root of x fac(x) x factorial answer last answer recall stack stack handling (see text) sum sum of the stack count no of items on stack average(x) average of x stack items (see text) lookup(x) returns the xth member of the stack clear(0) returns the sum of the stack and clears it e the value of e pi the value of pi arctan(x) the inverse tangent of x sec(x) the secant of x cosec(x) the cosecant of x cot(x) the cotangent of x arcsin(x) the inverse sine of x arccos(x) the inverse cosine of x arcsec(x) the inverse secant of x arccosec(x) the inverse cosecant of x arccot(x) the inverse cotangent of x sinh(x) the hyperbolic sine of x cosh(x) the hyperbolic cosine of x tanh(x) the hyperbolic tangent of x max(x,y) returns the larger of x and y min(x,y) returns the smaller of x and y greater(x,y) returns non zero if x > y otherwise it returns zero less(x,y) returns non zero if x < y otherwise it returns zero lesseq(x,y) returns non zero if x <= y otherwise it returns zero greateq(x,y) returns non zero if x >= y otherwise it returns zero equal(x,y) returns non zero if x = y otherwise it returns zero if(x,y,z) returns y if x is non zero otherwise it returns z deg(x) converts x from radians to degrees sign(x) returns -1 if x is negative, 0 if zero , 1 if positive round(x,y) returns x rounded to y decimal places or(x,y) returns non zero if x or y is non zero, otherwise returns zero and(x,y) returns non zero if x and y are non zero, otherwise returns zero not(x) returns non zero if x is zero, zero if x is non zero eor(x,y) returns non zero if x or y (but not both) are non zero comp(x) returns the two's complement of x ran(x,y) returns a random number between x and y. Many of these functions are reasonably self-explanatory, though some do need further discussion. Abs - Absolute This function returns the positive value of a number (or variable). Abs(10) would return 10, abs(-10) would also return 10. Fac - Factorial This function returns the factorial (shriek) value of a number, that is fac(x) returns x*(x-1)*(x-2)*...*2*1. So fac(6) would return 6*5*4*3*2*1=720. If this is passed a non integer, Scrivener automatically strips off the fractional part. Answer - Last answer recall This function will give an expression access to the result of the last calculation that Scrivener performed. Scrivener performs all its calculations much in the same way as we would read them, left to right and down the page. For instance, if [[ 7*5]] [[ answer-6]] were in the file the result would be 35 29 Stack - Stack handling This function can push a result onto a stack or it can take a result off the stack, depending on the context of the command. If it is an assignment ie stack=7.35, 7.35 would be pushed onto the stack, whereas result=stack would assign the upper most value of stack to result, then move the stack up one. When stack is used like this, it may be considered as any normal variable. Lookup - find a member of the stack. With the use of this command it is possible to implement a lookup table using the stack. If a number of results are pushed on to the stack, they can be looked up by this function, either in the order in which they were put on, or, in the more conventional way, of the last one in considered as the first. For example lookup(1) will find the first member put on the stack (assuming it has not since been removed) whilst lookup(-1) will find the last member put on. If lookup looks beyond the bound of the stack - zero is returned. Sum - the sum of all members on the stack. This variable is a sum of all the members of the stack and is updated as more things are put on or removed form the stack. This is cleared by the clear command. Count - the number of members on the stack. This variable holds the number of members on the stack and is incremented as things are put on the stack and decremented as they era removed. This is cleared by the clear command. Average - the average of a number of members. Average(x) will return the average of the first x members of the stack, average(-x) will return the average of the last x members to be put on the stack. Average(0) will average all the members on the stack. If a number of members is specified which is greater than the number on the stack, the others will be assumed to be zero. If - conditional This function allows conditional calculations to be made, so if a different calculation has to made dependent on the value of a variable, this should be able to do it. If for instance, discount is given depending on the number of objects bought dis=if(and(great(no,100),less(no,1000)),10,5) will assign to variable dis the value 10 if variable no is greater than 100,and less than 1000 otherwise it will assign the value 5 to dis. The if statement merely looks to see if its first parameter is non zero, and does the assignments appropriate, the functions and,great and less actually do the comparisons and return non zero or zero according to the conditions. Round - round a number This function can round a figure to an appropriate number of decimal places given by its second parameter. If this number is positive, Scrivener rounds to that many decimal places and if it is negative it will round to that many places prior to the decimal point. For example round(12345.6789,2) will give 12345.67 while round(12345.6789,-2) will give 12300 To actually round a variable you must reassign it. E.g round(x,3) will not actually round x to 3 places, but it will make the answer equal to x rounded to 3 decimal places, x=round(x,3) will, however, round x to 3 places and then reassign that to the variable x. Comp - two's complement This function will return the two's complement value of the integer passed to it. If not passed an integer, it will strip off the fractional section. For example x=comp(10) will assign to x the value of -11 (the two's complement of 10). Ran - generate a random number Ran(x,y) will return a decimal value between x and y. If only one parameter is specified, the other is assumed as zero. So ran(5) will return a value between zero and five. ran(10,-3) will return a value between -3 and 10. 6. Techniques. This section will attempt to cover the techniques of using Scrivener in some way towards its full extent, covering those little tricks which can be used to improve the performance of your source file. The first thing to be aware of is that Scrivener output file can be associated with a physical device such as the console, printer, modem etc. This is done by naming the output file as follows:- If you want output to: the console use file name con: the list device use file name lst: the RS232 port use file name pun: This is useful when testing out some of Scrivener functions, or to check if your source file is going to give out exactly what you expect before putting it to disk. The use of con: is especially useful. Equally it is possible to name con: as the input file name, this will then take lines from the keyboard rather than an input file, this allows testing of small sections of Scrivener source. Mail Shots. It is possible to use redirection files to allow the use of Scrivener as a mail shot utility in addition to its other functions. A redirection file is specified in the command line (ie when you actually type "Scrivener" to the prompt). This is done by preceding the file name by a "<" (less than) symbol. E.G. Scrivener