home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.barnyard.co.uk
/
2015.02.ftp.barnyard.co.uk.tar
/
ftp.barnyard.co.uk
/
cpm
/
walnut-creek-CDROM
/
CPM
/
DATABASE
/
SCRIVNER.LBR
/
SCRIV.DZC
/
SCRIV.DOC
Wrap
Text File
|
2000-06-30
|
112KB
|
2,846 lines
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 <in.fil
will take all subsequent input from the file called "in.fil". This means
that at any point that you have used a #input function, the input will no
longer come from the keyboard, but will come from the redirection file.
So if we created a file as follows:-
#input mac_name,,Please enter the customer name
#input mac_add1,,Please enter the address line 1
#input mac_add2,,line 2
#input mac_add3,,line 3
#input mac_add4,,line 4
#input mac_add5,,line 5
#input mac_title,,Enter the title (Sir, Madam etc)
mac_name
mac_add1
mac_add2
mac_add3
mac_add4
mac_add5
Dear mac_title,
Many thanks for your order which we received today, we
will send off your goods as soon as possible.
Yours sincerely,
Mr. M. Director.
and passed it through Scrivener as normal, everything would occur as we
should expect, asking you for the name and address and producing the output
file consisting of a standard letter thanking the customer for his order,
something along the lines of:-
Mr. C. Ustomer
The House
The Street
The Town
The County
The Postcode
Dear Sir,
Many thanks for your order which we received today, we
will send off your goods as soon as possible.
Yours sincerely,
Mr. M. Director.
depending upon the input you gave. Using a redirection file, however, we
could have Mr. Ustomer's name, address and title held in a separate file so
you need only type in
Scrivener <address.fil
and the name of the input and output files at the prompt. Scrivener then
takes a line of the redirection file to act as each line of input which you
would give, so Mr. Ustomer's file would look like:-
Mr. C. Ustomer
The House
The Street
The Town
The County
The Postcode
Sir
The full potential of this feature is only realised when doing a mail
shot, which is specified by typing a -m in the command line.
Let us assume that the source file given above was called stanlet on the
disk and we wanted to mail merge this with a file which contained some
names, addresses and titles called address.fil. At the CP/M prompt we would
type
Scrivener -m <address.fil
and Scrivener would ask for the input file. We would type
stanlet
and then the output file name at the prompt. Scrivener would then
churn through the names and addresses an produce a long file of
standard letters each with a separate name, address and title
given by the redirection file. This can then be split up or
printed directly or used in whatever way you wish.
For example, if address.fil was
Mr. C. Ustomer
The House
The Street
The Town
The County
The Postcode
Sir
A.N. Other
A Different House
Possibly the same Street
A town
And A County
An all important Postcode
Anthony
J.C. Scrivener
A Flat number, In a block
In a road
In a City
In a county
With a Postcode
Sir
and we used it with the stanlet above we would get a file which
would read:-
Mr. C. Ustomer
The House
The Street
The Town
The County
The Postcode
Dear Sir,
Many thanks for your order which we received today, we
will send off your goods as soon as possible.
Yours sincerely,
Mr. M. Director.
A.N. Other
A Different House
Possibly the same Street
A town
And A County
An all important Postcode
Dear Anthony,
Many thanks for your order which we received today, we
will send off your goods as soon as possible.
Yours sincerely,
Mr. M. Director.
J.C. Scrivener
A Flat number, In a block
In a road
In a City
In a county
With a Postcode
Dear Sir,
Many thanks for your order which we received today, we
will send off your goods as soon as possible.
Yours sincerely,
Mr. M. Director.
This file can then be printed under your word processor etc.
It is possible to mail merge directly from the keyboard, ie not using a
redirection file. To do this merely don't use the "<" symbol or redirection
file name (still use the -m directive, though). All input will be expected
from the keyboard. Once all input has been finished type ^z (control z)
before pressing return for the last line.
Use of #repeat.
The #repeat function was described briefly in the macro section of this
documentation. It was said that this could only repeat a single line of
text. Strictly speaking this is true, but it is not difficult to overcome
this. By repeating a line which contains a #include, it is possible to
repeatedly include a file which may further consist of text and macro
commands (even more repeats and includes). This is useful for calculation
based applications. One such example is given here to calculate correlation
coefficients for a number of points:-
#announce Calculating a population correlation coefficient.
Population Correlation Coefficients
===================================
[[def4.0]] [[de This is a comment the def4.0 defines the format as floating point of field 4 ]]
[[d n=0]] [[de set up number of points as zero]]
+----------------------------------------------------------------------------+
| x y x^2 y^2 xy |
+----------------------------------------------------------------------------+
#input mac_number,,Enter the number of points
#repeat #include correl.fil,,mac_number
[[d n=mac_number]] [[de number of points]]
----------------------------------------------------------------------------
[[t sx ]] [[t sy ]] [[t sxs ]] [[t sys ]] [[t sxy ]]
===========================================================================
[[de sx is the sum of all the x co-ordinates]]
[[de sy the sum of all y co-ordinates]]
[[de sxs the sum of x squared]]
[[de sys the sum of y squared]]
[[de sxy the sum of x*y ]]
Population coefficient is given by sum(xy) - sum(x)*sum(y)/n
-------------------------------------------------
sqr[((sum(x)^2)-(sum(x)^2)/n))*((sum(y)^2)-((sum(y)^2)/n)]
= [[o sxy ]] - [[o a= sx*sy/n]]
---------------------------------------
sqr[ [[o b=sxs-((sx^2)/n)]] * [[o c=sys-((sy^2)/n)]] ]
[[def5.1]]
= [[o a=sxy-a]]
------------------
[[o b=(b*c)^0.5 ]]
[[def5.4]]
= [[ a/b ]]
This file is quite straight forward, the first section dealing with
producing columns of figures. The initial input statement takes the number
of points that we want to correlate. The following statement is a repeated
include. This will include the file correl.fil the number of times that is
has been asked for. correl.fil looks like this:-
#input mac_x,,Enter the x co-ordinate
#input mac_y,,Enter the y co_ordinate
[[d x=mac_x]] [[d y=mac_y]]
[[ x ]] [[ y ]] [[ x^2 ]] [[ y^2 ]] [[ x*y ]]
and each time it is repeated, it asks for the x and y co-ordinates and sets
up columns of figures ready for the correlation. Care has to be used to
ensure that the columns line up with the total requests. All this is
included in the file as Scrivener churns through, doing all the calculations
at the end of the original file, to calculate the correlation.
Ultimately it produces an output file like :-
Population Correlation Coefficients
===================================
+----------------------------------------------------------------------------+
| x y x^2 y^2 xy |
+----------------------------------------------------------------------------+
10 6 100 36 60
7 4 49 16 28
12 7 144 49 84
12 8 144 64 96
9 10 81 100 90
16 7 256 49 112
12 10 144 100 120
18 15 324 225 270
8 5 64 25 40
12 6 144 36 72
14 11 196 121 154
16 13 256 169 208
----------------------------------------------------------------------------
146 102 1902 990 1334
===========================================================================
Population coefficient is given by sum(xy) - sum(x)*sum(y)/n
-------------------------------------------------
sqr[((sum(x)^2)-(sum(x)^2)/n))*((sum(y)^2)-((sum(y)^2)/n)]
= 1334 - 1241
---------------------------------------
sqr[ 126 * 123 ]
= 93
------------------
124.3
= 0.748
as you input all the points, and Scrivener does the necessary calculations,
and adding up all the totals requested for on the line above the line of
===.
This example also illustrates the use of the delete line function for
both comments in the source file, for the side working done in the included
file and for side working in the main file.
Macro Names.
When setting up names for macros, try (as far as is possible) to use
names likely to be unique in the text file (apart from where you want them
used). As some examples show in this text, I have a habit of starting my
macros with "mac_" (or "scr_" etc. as I find it easier to understand) as I
can think of no time when I would use "mac_" to begin a word.
Macro names can be more than one word (though the separating space is
taken literally and Scrivener looks specifically for that space - not a tab,
two spaces or a new line) and using more than one word can be helpful as is
illustrated under the section about using control characters for setting up
a printer.
Use of #random.
The #random function and its syntax is outlined in the macro section, its
use, however may need some explanation.
The random function allows the output of the likes of a standard letter
to be varied slightly, making each actual letter appear to have been written
specifically for the individual concerned. As an example, a thank you letter
generator, can be written quite simply under Scrivener, and using this
function we can vary the way of actually saying thank you, and using the
input function we can add little comments here and there. A sample one would
go something like
#input who_to,,Who is this letter to
#input from_who,,Who is it from
#input what_for,,What are you thanking them for
#input use_for,,What would you use it for
#input a_comment,,What comment will you make
#input end_it,,How will you end the letter (Yours sincerely etc.)
#random thank_1,,thank you for,,many thanks for,,It was kind of you to give me,,How generous it was of you to send me,,I was most pleased with
Dear who_to,
thank_1 what_for that you sent me recently. I will
use_for a lot. a_comment
end_it
from_who
and this will produce a letter with a random way of saying thank you.
Obviously this function has many more applications where mailshots need
de-mechanization.
A use of #include.
The #input function can be used to influence an '#include' function to
great effect, allowing the user to specify an included file which may differ
from letter to letter. For example you could set up a library of standard
letter headings each of which can be #included into a letter at the run
time, setting up the beginning of a letter which looks like:-
#input file_to_use,,Enter the file which contains the letter heading
#include file_to_use
and this will then allow the person running this letter under Scrivener
to specify the letter heading (again, good file names make this function far
more natural to use - especially for some third party).
It is possible to have
#include con:
in your source, and this will (as expected) take input from the keyboard as
if it were a file (ending with a control z to return back to the calling
file). Equally rdr: could be used to accept input from the RS232 port.
Producing a neat screen output.
The ability to use control characters both inside definitions and
inside the names they are recognized by, is particularly useful. One such
use for them is to be able to produce neat screen output by embedding screen
control characters for your terminal in announce and publish statements.
More easily done is to set up a file of definitions which can be #included
when writing an application. These would go something like:-
#define scr_clear,,^z
#define scr_home,,^~
#define scr_bs,,^h
and so on. In a file the author could write
#announce scr_clearThe screen should now be clear
Equally it is possible to have a library of printer control
definitions which can replace a printer command with the
appropriate characters. So it is possible to set up something
like:-
#define prn_form,,^L
#define prn_condensed,,^O
#define prn_condense_off,,^Q
and then in file typing
prn_condensed
will insert the control characters necessary to set up condensed
mode (for an Epson printer) when this is sent to the printer. It
is a good idea if setting up a letter to be used with mail merge,
to end the letter with a form feed, then the output file can be
sent immediately (or using prn: as the output file) with the
printer form feeding after each letter.
An interesting form of this, is to set up your library along
the lines of:-
#define condensed on,,^O
#define condensed off,,^Q
#define elite on,,^[M
#define elite off,,^[!0
and so on (though be careful that your source does not contain
these names where you don't want them - such is the advantage of
using uncommon macro names). Then in the source you can have
#input p_type,,What printer feature do you want
p_type
and at run time, typing "condensed on" to the prompt will replace
p_type with the control characters needed (ie control O). Using
this effect as well as using the ^^ to obtain a single ^ in
a macro can have unforeseen effects and is best avoided if
possible.
One thing to be careful of is the use of control z, this is
recognized as an end of file marker and can cause problems if put
in files.
Using control characters in definitions.
It is quite possible to use control character sequences in both
definitions and names.
The use of control characters in names can be used for
removing control characters etc. or for making them show up more
clearly for typesetting applications (as one example).
As an illustration (for all you typesetters out there) this
Scrivener source file would ask you for the file you want tabs
replaced in and what character (or characters) you wish it
replaced by. This will produce, in your specified output file, a
copy of your named file with all the tabs replaced by the
appropriate characters.
#input mac_file,,Which file need its tabs replaced
#input mac_tab,,What character(s) do you wish tab replaced by
#define ^I,,mac_tab
#include mac_file
This illustrates another point about definitions of macros,
that is, that the definition is always checked to see if it
contains previously defined macros and they are replaced before
the definition is made.
Long calculations.
It is quite likely that some calculations may be far longer
than would be liked and will not fit into columns easily (and not
without having to leave huge spaces in between the columns). Use
of booleans and conditionals are especially prone to this.
The easiest way around this is to have the calculation
performed on a deleted line, assign the result to a short
variable and use that in your columns, e.g.
[[ rebate=if(and(less(tax,50),greater(tax,10)),7,0)]]
can be more conveniently written as
[[d rebate=if(and(less(tax,50),greater(tax,10)),7,0)]]
[[ rebate]]
as in the final output file the upper line will be deleted and
the resultant lower line is much smaller and easier to put into
columns.
Generating an integral random number.
Using the ran and round functions it is easy to generate an
integral random number. For instance
[[ round(ran(3,18),0)]]
will give an integer between 3 and 18.
A calculator in Scrivener.
A simple two line Scrivener source will turn it into a
calculator which will do all the basic functions of the
calculator (though not stack or variable use).
#input mac_calc,,^j^j^jWhat do you wish calculated
[[dp mac_calc = ,,mac_calc,, ]]
is the simple program needed and if combined with mail merge you
can do repeated calculations until ^Z is typed.
The accuracy of the expression analyser.
The expression analyser uses floating point numbers (using 64 bits in
standard I.E.E.E. format), and as such, is prone to slight inaccuracies when
calculations to large numbers of decimal places are attempted. This package
is to be accurate to 10 places (or 0.01 pence in a million pounds).
truncation errors will obviously occur if large divisions are made and then
the result multiplied back up.
unusual forms of calculations.
The calculator section of Scrivener is remarkably powerful, albeit
using a floating point package. It allows assignments of variables inside
brackets in some very unusual positions. For example:-
b=(c=10)+(d=9/(e=5-2))
will set up e=3 (5-2)
d=3 (9/e)
c=10
and b=13 (10+d)
This can lead to a valuable, if confusing at first,
shorthand, especially in connection with a conditional statement.
Rather than having to set up each calculation individually and then apply
a conditional i.e.:-
[[ code1=7]] [[ code2=8]]
[[ code=if(equal(tax,9),code1,code2)]]
which sets code1 to 7, code2 to 8, and will set code to code1 if tax is 9 or
code2 if it isn't,
[[ code=if(equal(tax,9),(code1=7),(code2=8))]]
will do exactly the same thing.
The use of the '^' symbol.
The '^', as has previously been said, can be used to insert control
characters into definitions, names, announce lines, calculator print lines
etc.. In general, using the '^' symbol results in the next character being
turned into a control character, E.g. ^A would be replaced with ASCII 1 ^B
with ASCII 2 etc.
There are, however, a few exceptions to this rule. A '^^' will give a
single '^' on output (to obtain the ASCII character 30 use ^~). Using '^@'
will merely give an '@' symbol as ASCII 0 is an en of line marker and can
cause problems. The '^]' will give a ']', this allows output of a Scrivener
file to contain Scrivener commands, which can be used at a later date by
Scrivener.
E.g.
[[p [[ 12*5 ^]^] is the result of 12*5 ]]
will cause an output to the screen (or redirection file with the M - mail to
file command) which would be:-
[[ 12*5]] is the result of 12*5
As this has set up the correct brackets ( with the sneaky use of the control
characters ), this can then be passed through Scrivener again for other
functions.
7. Worked Examples.
A fictitious invoice generator.
This invoice generator, will adequately cope with handling small
invoices, using an easily changeable look up table of prices. It is more
convenient to have the lookup table #included at the beginning of a file.
The main source would look like
#include price.fil
#include names
#input h_file,,Which file contains your business header
#include h_file
mac_name
mac_add1
mac_add2
mac_add3
mac_add4
mac_add5
[[def 4.2t]]
Invoice for:-
Items Description cost/item sub-total
#input mac_items,,Please Enter the number of Boogle flips
[[d no=mac_items]]
[[ no]] Boogle flips [[ c= lookup(1)]] [[z no*c]]
#input mac_items,,Please Enter the number of Grobel brendels
[[d no=mac_items]]
[[ no]] Grobel brendels [[ c=lookup(2)]] [[z no*c]]
#input mac_items,,Please Enter the number of Farent Zotrons
[[d no=mac_items]]
[[ no]] Farent Zotrons [[ c=lookup(3)]] [[z no*c]]
sub-total [[t stotal]]
vat [[ tax=stotal*0.15]]
Total [[ stotal+tax]]
note that all the lines will be deleted with the z - delete if zero -
function if no items are required. The files which are #included at the
beginning are the file of prices which would look like:-
#announce ^m^j^jIncluding price list
[[d stack=2.50]] [[de cost of boogle flips]]
[[d stack=3.80]] [[de cost of Grobel brendels]]
[[d stack=0.80]] [[de cost of Farent Zotrons]]
[[d stack=0.50]]
[[d stack=1.45]]
[[d stack=9.95]]
[[d stack=6.95]]
[[d stack=6.5]]
and a file of questions to ask for customer name and address. This is
generally a good idea, as they can be #included in many source texts,
without having to be re-typed each time. These would look something like:-
#input mac_name,,Enter Customer Name
#input mac_add1,,Enter the address (5 lines)
#input mac_add2,,
#input mac_add3,,
#input mac_add4,,
#input mac_add5,,
the other include asks the user to type in the business header, again a good
idea, so that different headers can be used, without recourse to changing
the original source (this ability is essential when handling standard
letters).
A.R.M.C. A.S.
(c) MML Systems Ltd 1985 1986