summaryrefslogtreecommitdiff
path: root/support/flow
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/flow
Initial commit
Diffstat (limited to 'support/flow')
-rw-r--r--support/flow/COPYING340
-rw-r--r--support/flow/README38
-rw-r--r--support/flow/flow.c846
-rw-r--r--support/flow/flowdoc.pdfbin0 -> 104345 bytes
-rw-r--r--support/flow/flowdoc.tex783
5 files changed, 2007 insertions, 0 deletions
diff --git a/support/flow/COPYING b/support/flow/COPYING
new file mode 100644
index 0000000000..5b6e7c66c2
--- /dev/null
+++ b/support/flow/COPYING
@@ -0,0 +1,340 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/support/flow/README b/support/flow/README
new file mode 100644
index 0000000000..4581819be7
--- /dev/null
+++ b/support/flow/README
@@ -0,0 +1,38 @@
+SHORT: makes flowcharts for the LaTeX picture environment
+
+Flow 0.99g 2004-2-18
+
+Summary : flow reads a simple flow chart description file and produces the
+ corresponding LaTeX picture environment
+
+Files in flow099g.tar.gz
+
+ flow.c - plain C code, should be portable
+ flowdoc.tex - documentation in LaTeX
+ README - this file
+ COPYING - GNU GPL license
+
+Note:
+
+flow.c uses tmpnam instead of mkstemp, gcc says this is bad, but I'm
+not sure what the portability implications are when using mkstemp
+
+flowdoc.tex is old style 2.09 LaTeX, but being vanilla LaTeX is works
+fine in compatibility mode
+
+Revision history
+
+(99j is a Japanese packaging of 99c)
+
+0.99g - command scanning overflow fixed, thanks Jean-Michel Rouet, 2009-10-30
+0.99f - % comment command added by Joost Bruynooghe
+0.99e - GPL'ed
+0.99d - more bugs, clarity
+0.99c - removed bug in Up,Down,Left,Right bounding
+0.99b - unlink() -> remove() for ANSI C compatibility (whoops)
+0.99 - writes an appropriate \begin{picture} command around the output
+ (thanks to Brad Clements for the (obvious :-) suggestion)
+0.98 - allowed for non-square Choice boxes
+0.97 - removed non-ANSI strnicmp
+0.96 - easier on VMS systems
+0.95 - first release
diff --git a/support/flow/flow.c b/support/flow/flow.c
new file mode 100644
index 0000000000..525cfb96f8
--- /dev/null
+++ b/support/flow/flow.c
@@ -0,0 +1,846 @@
+#define VERSION "0.99f"
+
+/*
+
+flow.c 22/1/93 (C) 2005 Terry Brown
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*/
+
+/*
+
+flow - a flow-chart -> LaTeX generator. Parses a file in a flow-chart
+specification language, then produces a corresponding LaTeX
+pic environment.
+
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <string.h>
+
+typedef int bool;
+
+#define TRUE 1
+#define FALSE 0
+
+typedef struct {float x,y;} coord;
+
+typedef struct {char name[80];
+ int Params;
+ coord size;
+ bool HasText;
+ } FlowCom;
+
+#define ParamLen 120
+#define LineLen 120
+
+typedef char param[ParamLen];
+
+#define MaxBoxes 2048 /* could not possibly have more than this */
+
+#define Commands 16
+
+FlowCom fcom[Commands] = {
+ { "SetTrack", 1, {0,0}, FALSE },
+ { "Up", 1, {0,0}, FALSE },
+ { "Down", 1, {0,0}, FALSE },
+ { "Left", 1, {0,0}, FALSE },
+ { "Right", 1, {0,0}, FALSE },
+ { "Box", 0, {4,2}, TRUE },
+ { "Oval", 0, {4,2}, TRUE },
+ { "Choice", 4, {4,4}, TRUE },
+ { "Tag", 0, {0,0}, FALSE },
+ { "ToTag", 0, {0,0}, FALSE },
+ { "Scale", 2, {0,0}, FALSE },
+ { "Tilt", 0, {4,2}, TRUE },
+ { "Text", 0, {4,2}, TRUE },
+ { "TxtPos", 4, {0,0}, FALSE },
+ { "Skip", 2, {0,0}, FALSE },
+ { "%", 0, {0,0}, FALSE }
+};
+
+typedef enum {SetTrack,
+ Up,
+ Down,
+ Left,
+ Right,
+ Box,
+ Oval,
+ Choice,
+ Tag,
+ ToTag,
+ Scale,
+ Tilt,
+ Text,
+ TxtPos,
+ Skip,
+ Comment
+ } TheCommands;
+
+typedef enum {ArrowS, LineS, NoneS} trackSymb;
+typedef enum {UpD, DownD, LeftD, RightD} direcs;
+
+typedef struct ATAG {coord pos;
+ coord size;
+ struct ATAG *next;
+ } aTag;
+
+typedef struct {
+ coord min;
+ coord max;
+} boundingBox;
+
+
+/* state / position tracking variables */
+
+boundingBox pic = {{0,0},{0,0}};
+coord Coords[MaxBoxes] = {{0,0}}; /* just initialise first coord */
+int CurCoord = 0;
+int CurTrack = ArrowS;
+int CurDirec = DownD;
+coord CurScale = {1.,1.};
+coord CurSize = {0.,0.};
+aTag *CurTag = NULL;
+char CurPos[20] = "[c]";
+char CurBoxPos[20] = "[c]";
+char leader[20]="";
+char tailer[20]="";
+float TrackX = 1.;
+float TrackY = 1.;
+int InputLine = 0;
+char line[LineLen];
+
+float VertGap=1.;
+float HorzGap=1.;
+
+FILE *inFile, *outFile; /* global input output streams */
+
+int doText();
+
+void checkBounds(boundingBox *b, coord *c) {
+
+ if (b->min.x > c->x) b->min.x = c->x;
+ if (b->max.x < c->x) b->max.x = c->x;
+ if (b->min.y > c->y) b->min.y = c->y;
+ if (b->max.y < c->y) b->max.y = c->y;
+}
+void checkBoundsRng(
+ boundingBox *b,
+ float x,
+ float y,
+ float sx,
+ float sy
+ ) {
+
+ if (b->min.x > x) b->min.x = x;
+ if (b->max.x < x+sx) b->max.x = x+sx;
+ if (b->min.y > y) b->min.y = y;
+ if (b->max.y < y+sy) b->max.y = y+sy;
+}
+
+int getCommand(char line[], param plist) {
+/*
+tries to interpret the next line of inFile as a command, returns -1 if it can't
+*/
+
+ int i=0, command = -1;
+
+ while (i<Commands) {
+
+ if ( strncmp(fcom[i].name,line,strlen(fcom[i].name)) == 0) {
+ command = i;
+ break;
+ }
+ i++;
+ }
+
+ if (command == -1) {
+ if (!feof(inFile) && line[0] != '\n')
+ fprintf(stderr,"flow error : can't interpret line %d\n",InputLine);
+ return command;
+ }
+
+ strncpy(plist, line+strlen(fcom[command].name), ParamLen);
+
+ return command;
+
+}
+
+
+int doCommand(int command, param pList) {
+/*
+output the LaTeX bits for this command, updating the coords, coord list
+etc. as required
+*/
+
+ static int init = 0;
+ aTag *tempTag;
+ char params[10][80];
+ char *trackStr = "vector";
+ float dimen,x,y,x1,y1;
+ int i,xs,ys;
+ coord t;
+
+ dimen = 0.;
+
+ params[0][0]=0; /* so Up / Down / Left / Right can find *'s for line
+ drawing */
+
+
+ if (CurTrack == LineS) trackStr = "line";
+
+ if (fcom[command].HasText) {
+ if ((command != Choice && sscanf(pList,"%f %f",&x,&y) == 2) ||
+ (command == Choice && sscanf(pList,"%s %s %s %s %f %f",
+ params[0],
+ params[0],
+ params[0],
+ params[0],
+ &x,&y) == 6)) {
+ fcom[command].size.x = x;
+ fcom[command].size.y = y;
+ }
+ }
+
+ if (!init && CurSize.x == 0. && CurSize.y == 0.) {
+ CurSize.x = fcom[command].size.x*CurScale.x;
+ CurSize.y = fcom[command].size.y*CurScale.y;
+ }
+
+ if ( init && (fcom[command].size.x != 0 || fcom[command].size.y != 0 )) {
+
+ switch (CurDirec) {
+
+ case DownD :
+
+ t.x = Coords[CurCoord].x+CurSize.x/2;
+ t.y = Coords[CurCoord].y-CurSize.y;
+
+ if (CurTrack != NoneS)
+ fprintf(outFile,"\\put(%3.4f,%3.4f){\\%s(%d,%d){%3.4f}}\n",
+ t.x,
+ t.y,
+ trackStr,
+ 0,-1,
+ VertGap);
+
+ checkBounds(&pic,&t);
+
+ Coords[CurCoord+1].x = Coords[CurCoord].x + CurSize.x/2 -
+ fcom[command].size.x*CurScale.x / 2;
+
+ Coords[CurCoord+1].y = Coords[CurCoord].y - CurSize.y
+ - VertGap;
+
+ checkBounds(&pic,Coords+CurCoord+1);
+
+ break;
+
+ case UpD :
+
+ t.x = Coords[CurCoord].x+CurSize.x/2;
+ t.y = Coords[CurCoord].y;
+
+ if (CurTrack != NoneS)
+ fprintf(outFile,"\\put(%3.4f,%3.4f){\\%s(%d,%d){%3.4f}}\n",
+ t.x,
+ t.y,
+ trackStr,
+ 0,1,
+ VertGap);
+
+ checkBounds(&pic,&t);
+
+ Coords[CurCoord+1].x = Coords[CurCoord].x + CurSize.x/2 -
+ fcom[command].size.x*CurScale.x / 2;
+
+ Coords[CurCoord+1].y = Coords[CurCoord].y +
+ fcom[command].size.y*CurScale.y
+ + VertGap;
+ checkBounds(&pic,Coords+CurCoord+1);
+
+ break;
+
+ case RightD :
+
+ t.x = Coords[CurCoord].x+CurSize.x;
+ t.y = Coords[CurCoord].y-CurSize.y/2;
+
+ if (CurTrack != NoneS)
+ fprintf(outFile,"\\put(%3.4f,%3.4f){\\%s(%d,%d){%3.4f}}\n",
+ t.x,
+ t.y,
+ trackStr,
+ 1,0,
+ HorzGap);
+
+ checkBounds(&pic,&t);
+
+ Coords[CurCoord+1].x = Coords[CurCoord].x + CurSize.x
+ + HorzGap;
+ Coords[CurCoord+1].y = Coords[CurCoord].y - CurSize.y/2 +
+ fcom[command].size.y*CurScale.y / 2;
+
+ checkBounds(&pic,Coords+CurCoord+1);
+
+ break;
+
+ case LeftD :
+
+ t.x = Coords[CurCoord].x;
+ t.y = Coords[CurCoord].y-CurSize.y/2;
+
+ if (CurTrack != NoneS)
+ fprintf(outFile,"\\put(%3.4f,%3.4f){\\%s(%d,%d){%3.4f}}\n",
+ t.x,
+ t.y,
+ trackStr,
+ -1,0,
+ HorzGap);
+
+ checkBounds(&pic,&t);
+
+ Coords[CurCoord+1].x = Coords[CurCoord].x -
+ fcom[command].size.x*CurScale.x
+ - HorzGap;
+ Coords[CurCoord+1].y = Coords[CurCoord].y - CurSize.y/2 +
+ fcom[command].size.y*CurScale.y / 2;
+
+ checkBounds(&pic,Coords+CurCoord+1);
+
+ break;
+
+ default:
+ break;
+ }
+ CurCoord++;
+ CurSize.x = fcom[command].size.x*CurScale.x;
+ CurSize.y = fcom[command].size.y*CurScale.y;
+
+ }
+
+ switch (command) {
+
+ case Skip :
+ if (sscanf(pList,"%f %f %f %f",&x,&y,&x1,&y1) == 4) {
+ VertGap = y;
+ HorzGap = x;
+ TrackX = x1;
+ TrackY = y1;
+ }
+ break;
+
+ case TxtPos :
+ CurPos[0]=CurBoxPos[0]=leader[0]=tailer[0]=0;
+ sscanf(pList,"%s %s %s %s",CurPos,CurBoxPos,leader,tailer);
+ break;
+
+ case Box :
+ init=1;
+ fprintf(outFile,"\\put(%3.4f,%3.4f){\\framebox(%3.4f,%3.4f)%s{\\shortstack%s{\n",
+ Coords[CurCoord].x,
+ Coords[CurCoord].y-CurSize.y,
+ CurSize.x,
+ CurSize.y,
+ CurBoxPos,
+ CurPos);
+ doText();
+ fprintf(outFile,"}}}\n");
+
+ checkBoundsRng(
+ &pic,
+ Coords[CurCoord].x,
+ Coords[CurCoord].y-CurSize.y,
+ CurSize.x,
+ CurSize.y
+ );
+
+ break;
+
+ case Tilt :
+ init=1;
+ fprintf(outFile,"\\put(%3.4f,%3.4f){\\makebox(%3.4f,%3.4f)%s{\\shortstack%s{\n",
+ Coords[CurCoord].x,
+ Coords[CurCoord].y-CurSize.y,
+ CurSize.x,
+ CurSize.y,
+ CurBoxPos,
+ CurPos);
+ doText();
+ fprintf(outFile,"}}}\n");
+
+ fprintf(outFile,"\\put(%3.4f,%3.4f){\\line(%d,%d){%3.4f}}\n",
+ Coords[CurCoord].x+1./6.*CurSize.y,
+ Coords[CurCoord].y,
+ 1,0,
+ CurSize.x);
+ fprintf(outFile,"\\put(%3.4f,%3.4f){\\line(%d,%d){%3.4f}}\n",
+ Coords[CurCoord].x-1./6.*CurSize.y,
+ Coords[CurCoord].y-CurSize.y,
+ 1,0,
+ CurSize.x);
+ fprintf(outFile,"\\put(%3.4f,%3.4f){\\line(%d,%d){%3.4f}}\n",
+ Coords[CurCoord].x-1./6.*CurSize.y,
+ Coords[CurCoord].y-CurSize.y,
+ 1,3,
+ CurSize.y*1./3.);
+ fprintf(outFile,"\\put(%3.4f,%3.4f){\\line(%d,%d){%3.4f}}\n",
+ Coords[CurCoord].x-1./6.*CurSize.y+CurSize.x,
+ Coords[CurCoord].y-CurSize.y,
+ 1,3,
+ CurSize.y*1./3.);
+
+ checkBoundsRng(
+ &pic,
+ Coords[CurCoord].x-1./6.*CurSize.y,
+ Coords[CurCoord].y-CurSize.y,
+ CurSize.x + 1./6.*CurSize.y,
+ CurSize.y
+ );
+
+ break;
+
+ case Text :
+ init=1;
+ fprintf(outFile,"\\put(%3.4f,%3.4f){\\makebox(%3.4f,%3.4f)%s{\\shortstack%s{\n",
+ Coords[CurCoord].x,
+ Coords[CurCoord].y-CurSize.y,
+ CurSize.x,
+ CurSize.y,
+ CurBoxPos,
+ CurPos);
+ doText();
+ fprintf(outFile,"}}}\n");
+
+ checkBoundsRng(
+ &pic,
+ Coords[CurCoord].x,
+ Coords[CurCoord].y-CurSize.y,
+ CurSize.x,
+ CurSize.y
+ );
+ break;
+
+ case Oval :
+ init=1;
+ fprintf(outFile,"\\put(%3.4f,%3.4f){\\oval(%3.4f,%3.4f)}\n",
+ Coords[CurCoord].x+CurSize.x/2,
+ Coords[CurCoord].y-CurSize.y/2,
+ CurSize.x,
+ CurSize.y );
+ fprintf(outFile,"\\put(%3.4f,%3.4f){\\makebox(%3.4f,%3.4f)%s{\\shortstack%s{\n",
+ Coords[CurCoord].x,
+ Coords[CurCoord].y-CurSize.y,
+ CurSize.x,
+ CurSize.y,
+ CurBoxPos,
+ CurPos );
+ doText();
+ fprintf(outFile,"}}}\n");
+ checkBoundsRng(
+ &pic,
+ Coords[CurCoord].x,
+ Coords[CurCoord].y-CurSize.y,
+ CurSize.x,
+ CurSize.y
+ );
+
+ break;
+
+ case Choice :
+
+ init=1;
+
+ xs = (int)CurSize.x; ys = (int)CurSize.y;
+
+ for (i = (xs>ys) ? xs : ys; i>1; i--) {
+ if ( (xs % i) == 0 && (ys % i) == 0 ) {
+ xs /= i;
+ ys /= i;
+ i = (xs>ys) ? xs : ys;
+ }
+ }
+
+ if (xs>6) {
+ fprintf(stderr,"Flow warning - illegal Choice aspect ratio\n");
+ xs = 6;
+ }
+ if (ys>6) {
+ fprintf(stderr,"Flow warning - illegal Choice aspect ratio\n");
+ ys = 6;
+ }
+
+ fprintf(outFile,"\\put(%3.4f,%3.4f){\\line(%d,%d){%3.4f}}\n",
+ Coords[CurCoord].x,
+ Coords[CurCoord].y-CurSize.y/2,
+ xs,ys,CurSize.x/2
+ );
+ fprintf(outFile,"\\put(%3.4f,%3.4f){\\line(%d,%d){%3.4f}}\n",
+ Coords[CurCoord].x,
+ Coords[CurCoord].y-CurSize.y/2,
+ xs,-ys,CurSize.x/2
+ );
+ fprintf(outFile,"\\put(%3.4f,%3.4f){\\line(%d,%d){%3.4f}}\n",
+ Coords[CurCoord].x+CurSize.x,
+ Coords[CurCoord].y-CurSize.y/2,
+ -xs,-ys,CurSize.x/2
+ );
+ fprintf(outFile,"\\put(%3.4f,%3.4f){\\line(%d,%d){%3.4f}}\n",
+ Coords[CurCoord].x+CurSize.x,
+ Coords[CurCoord].y-CurSize.y/2,
+ -xs,ys,CurSize.x/2
+ );
+ fprintf(outFile,"\\put(%3.4f,%3.4f){\\makebox(%3.4f,%3.4f)%s{\\shortstack%s{\n",
+ Coords[CurCoord].x,
+ Coords[CurCoord].y-CurSize.y,
+ CurSize.x,
+ CurSize.y,
+ CurBoxPos,
+ CurPos );
+ doText();
+ fprintf(outFile,"}}}\n");
+
+ sscanf(pList,"%s %s %s %s",params[0],params[1],params[2],params[3]);
+
+ if (params[0][0] != '.')
+ fprintf(outFile,"\\put(%3.4f,%3.4f){\\makebox(0,0)[lt]{%s}}\n",
+ Coords[CurCoord].x+
+ CurSize.x*0.65,
+ Coords[CurCoord].y,
+ params[0]
+ );
+
+ if (params[1][0] != '.')
+ fprintf(outFile,"\\put(%3.4f,%3.4f){\\makebox(0,0)[rt]{%s}}\n",
+ Coords[CurCoord].x,
+ Coords[CurCoord].y-
+ CurSize.y/2.*0.7,
+ params[1]
+ );
+
+ if (params[2][0] != '.')
+ fprintf(outFile,"\\put(%3.4f,%3.4f){\\makebox(0,0)[lt]{%s}}\n",
+ Coords[CurCoord].x+
+ CurSize.x,
+ Coords[CurCoord].y-
+ CurSize.y/2.*0.7,
+ params[2]
+ );
+
+ if (params[3][0] != '.')
+ fprintf(outFile,"\\put(%3.4f,%3.4f){\\makebox(0,0)[lb]{%s}}\n",
+ Coords[CurCoord].x+
+ CurSize.x*0.65,
+ Coords[CurCoord].y-
+ CurSize.y,
+ params[3]
+ );
+
+ checkBoundsRng(
+ &pic,
+ Coords[CurCoord].x,
+ Coords[CurCoord].y-CurSize.y,
+ CurSize.x,
+ CurSize.y
+ );
+ break;
+
+ case SetTrack :
+ sscanf(pList,"%s",params[0]);
+
+ if ( strcmp("arrow",params[0]) == 0)
+ CurTrack = ArrowS;
+ if ( strcmp("line",params[0]) == 0)
+ CurTrack = LineS;
+ if ( strcmp("none",params[0]) == 0)
+ CurTrack = NoneS;
+
+ break;
+
+ case Scale :
+ sscanf(pList,"%f %f",&CurScale.x,&CurScale.y);
+ break;
+
+ case Tag :
+ tempTag = (aTag*)malloc(sizeof(aTag));
+ tempTag->size.x = CurSize.x;
+ tempTag->size.y = CurSize.y;
+ tempTag->pos.x = Coords[CurCoord].x;
+ tempTag->pos.y = Coords[CurCoord].y;
+ tempTag->next = CurTag;
+ CurTag = tempTag;
+ break;
+
+ case ToTag :
+
+ if (CurTag == NULL) {
+ fprintf(stderr,"flow error - Tag stack empty \n");
+ break;
+ }
+ tempTag = CurTag;
+ CurSize.x = tempTag->size.x;
+ CurSize.y = tempTag->size.y;
+ Coords[CurCoord].x = tempTag->pos.x;
+ Coords[CurCoord].y = tempTag->pos.y;
+
+ CurTag = tempTag->next;
+
+ free(tempTag);
+
+ break;
+
+ case Right :
+ CurDirec = RightD;
+ if (sscanf(pList,"%f %19s",&dimen,params[0])>=1) {
+ init=1;
+ dimen *= TrackX;
+ if (CurTrack != NoneS)
+ fprintf(outFile,"\\put(%3.4f,%3.4f){\\%s(%d,%d){%3.4f}}\n",
+ Coords[CurCoord].x+CurSize.x,
+ Coords[CurCoord].y-CurSize.y/2,
+ (params[0][0]=='*')?"vector":"line",
+ 1,0,
+ dimen);
+
+ Coords[CurCoord+1].x = Coords[CurCoord].x + CurSize.x +
+ dimen;
+
+ Coords[CurCoord+1].y = Coords[CurCoord].y - CurSize.y/2;
+
+ CurCoord++;
+
+ CurSize = fcom[command].size;
+ }
+ checkBounds(&pic,&(Coords[CurCoord]));
+ break;
+
+ case Down :
+ CurDirec = DownD;
+
+ if (sscanf(pList,"%f %19s",&dimen,params[0])>=1) {
+ init=1;
+ dimen *= TrackY;
+ if (CurTrack != NoneS)
+ fprintf(outFile,"\\put(%3.4f,%3.4f){\\%s(%d,%d){%3.4f}}\n",
+ Coords[CurCoord].x+CurSize.x/2,
+ Coords[CurCoord].y-CurSize.y,
+ (params[0][0]=='*')?"vector":"line",
+ 0,-1,
+ dimen);
+
+ Coords[CurCoord+1].x = Coords[CurCoord].x + CurSize.x/2 -
+ fcom[command].size.x / 2;
+
+ Coords[CurCoord+1].y = Coords[CurCoord].y - CurSize.y
+ - dimen;
+
+ CurCoord++;
+
+ CurSize = fcom[command].size;
+ }
+ checkBounds(&pic,&(Coords[CurCoord]));
+
+ break;
+
+ case Left :
+ CurDirec = LeftD;
+ if (sscanf(pList,"%f %19s",&dimen,params[0])>=1) {
+ init=1;
+ dimen *= TrackX;
+ if (CurTrack != NoneS)
+ fprintf(outFile,"\\put(%3.4f,%3.4f){\\%s(%d,%d){%3.4f}}\n",
+ Coords[CurCoord].x,
+ Coords[CurCoord].y-CurSize.y/2,
+ (params[0][0]=='*')?"vector":"line",
+ -1,0,
+ dimen);
+
+ Coords[CurCoord+1].x = Coords[CurCoord].x -
+ dimen;
+
+ Coords[CurCoord+1].y = Coords[CurCoord].y - CurSize.y/2;
+
+ CurCoord++;
+
+ CurSize = fcom[command].size;
+ }
+ checkBounds(&pic,&(Coords[CurCoord]));
+ break;
+
+ case Up :
+ CurDirec = UpD;
+ if (sscanf(pList,"%f %19s",&dimen,params[0])>=1) {
+ init=1;
+ dimen *= TrackY;
+ if (CurTrack != NoneS)
+ fprintf(outFile,"\\put(%3.4f,%3.4f){\\%s(%d,%d){%3.4f}}\n",
+ Coords[CurCoord].x+CurSize.x/2,
+ Coords[CurCoord].y,
+ (params[0][0]=='*')?"vector":"line",
+ 0,1,
+ dimen);
+
+ Coords[CurCoord+1].x = Coords[CurCoord].x + CurSize.x/2 -
+ fcom[command].size.x / 2;
+
+ Coords[CurCoord+1].y = Coords[CurCoord].y +
+ dimen;
+
+ CurCoord++;
+
+ CurSize = fcom[command].size;
+ }
+ checkBounds(&pic,&(Coords[CurCoord]));
+ break;
+
+ case Comment :
+ break;
+
+ default:
+ fprintf(stderr,"flow error : unknown command %4d\n",command);
+ return 0;
+ }
+
+ if (command != Scale) CurScale.x = CurScale.y = 1.;
+
+ if (fcom[command].HasText == FALSE) {
+ line[0]=0;
+ fgets(line,LineLen,inFile);
+ InputLine++;
+ }
+
+ return 1;
+
+}
+
+int doText() {
+/*
+output text for those commands that require it, spit out all lines that start
+with white space (0x20, 0x09)
+*/
+
+ int i;
+
+ line[0]=0;
+ fgets(line,LineLen,inFile);
+ InputLine++;
+
+ while (!feof(inFile) && (
+ line[0] == 0x20 ||
+ line[0] == 0x09 )
+ ) {
+
+ line[strlen(line)-1]=0;
+ for (i=0; i<strlen(line) &&
+ (line[i] == 0x09 || line[i] == 0x20); i++);
+
+ fprintf(outFile,"%s%s%s",leader,line+i,tailer);
+ line[0]=0;
+ fgets(line,LineLen,inFile);
+ InputLine++;
+
+ if (line[0] == 0x20 || line[0] == 0x09 )
+ fprintf(outFile,"\\\\\n");
+ else
+ fprintf(outFile,"\n");
+
+ }
+
+ return 1;
+}
+
+void applyPicWrapper(FILE *inFile, FILE *outFile) {
+
+ char buf[1024];
+
+ fprintf(outFile,"\\begin{picture}(%f,%f)(%f,%f)\n",
+ pic.max.x - pic.min.x,
+ pic.max.y - pic.min.y,
+ pic.min.x,
+ pic.min.y
+ );
+
+ while (!feof(inFile)) {
+
+ fwrite(buf,fread(buf,1,1024,inFile),1,outFile);
+
+ }
+
+ fprintf(outFile,"\\end{picture}\n");
+}
+
+int main(int argc, char **argv) {
+
+ param params;
+ int command=0;
+ char tmpfileNm[80];
+
+
+ inFile = stdin; outFile = stdout;
+
+ tmpnam(tmpfileNm);
+ outFile = fopen(tmpfileNm,"w");
+
+ if (argc > 1) {
+ inFile = fopen(argv[1],"r");
+ if (inFile == NULL) {
+ fprintf(stderr,"Couldn't open input file %s\n",argv[1]);
+ exit(0);
+ }
+ }
+
+ line[0]=0;
+ fgets(line,LineLen,inFile);
+ InputLine++;
+
+ fprintf(outFile,"%% picture environment flowchart generated by flow ");
+ fprintf(outFile,"%s\n",VERSION);
+
+ while (command != -1) {
+
+ command = getCommand(line,params);
+
+ if (command != -1)
+ if (!doCommand(command, params)) return 10;
+ }
+
+ fclose(inFile);
+ fclose(outFile);
+
+ outFile = stdout;
+ if (argc > 2) {
+ outFile = fopen(argv[2],"w");
+ if (outFile == NULL) {
+ fprintf(stderr,"Couldn't open output file %s\n",argv[2]);
+ fclose(inFile);
+ exit(0);
+ }
+ }
+
+ inFile = fopen(tmpfileNm,"r");
+
+ applyPicWrapper(inFile,outFile);
+ if (outFile != stdout) fclose(outFile);
+ fclose(inFile);
+ remove(tmpfileNm);
+
+ exit(0);
+
+ return 0; /* just to suppress the warning */
+
+}
diff --git a/support/flow/flowdoc.pdf b/support/flow/flowdoc.pdf
new file mode 100644
index 0000000000..43e4d2a8c0
--- /dev/null
+++ b/support/flow/flowdoc.pdf
Binary files differ
diff --git a/support/flow/flowdoc.tex b/support/flow/flowdoc.tex
new file mode 100644
index 0000000000..9a0e7469b1
--- /dev/null
+++ b/support/flow/flowdoc.tex
@@ -0,0 +1,783 @@
+% flowdoc.tex - a fairly plain LaTeX file, documentation for 'flow'
+% created 15 Nov 1992, by Terry Brown
+% last revised 2004-2-18
+
+\documentstyle{article}
+
+\setlength{\unitlength}{2em} % for the picture environment
+
+\setlength{\parindent}{0pt}
+\setlength{\parskip}{2ex}
+\addtolength{\topmargin}{-1cm}
+\addtolength{\textheight}{2cm}
+\addtolength{\evensidemargin}{-1cm}
+\addtolength{\oddsidemargin}{-1cm}
+\addtolength{\textwidth}{2cm}
+% 4 levels of headings
+\newcommand{\headA}[1]{{\huge \vspace{1ex} \bf \hfill #1 \vspace{1ex}\hfill}}
+\newcommand{\headB}[1]{{\Large \vspace{1ex} \bf #1 \vspace{1ex} }}
+\newcommand{\headC}[1]{{\large \vspace{1ex} \bf #1 \vspace{1ex} }}
+\newcommand{\headD}[1]{{\bf \vspace{1ex} #1 \vspace{1ex} }}
+
+\newcommand{\pushin}{\hspace*{1em}}
+
+\begin{document}
+
+\title{Flow -- a program to generate flowcharts in the \LaTeX\
+ picture environment}
+\author{Terry Brown}
+\date{November 25, 1992 --- September 22, 2005}
+\maketitle
+
+\headB{Summary}
+
+{\em Flow\/} is a small program which parses the flowchart description
+explained in this document and translates it to the \LaTeX\ picture
+environment.
+
+Flow acts as a filter, so a typical execution would be...
+
+\verb+flow +$<$\verb+myprog.flo +$>$\verb+myprog.pic+
+
+...where \verb+myprog.flo+ is a plain text file containing a description of a
+flowchart, and \verb+myprog.pic+ will be a plain text file containing the
+body of a \LaTeX\ picture environment to draw the flowchart. Alternatively
+
+\verb+flow inputFile + or \verb+ flow inputFile outputFile+
+
+may be used. VMS users see notes at end.
+
+\verb+myprog.pic+ could either be inserted into a picture environment in a
+\LaTeX\ file with a text editor, or pulled in by the \verb+\input+ command as
+\LaTeX\ is run.
+
+\headB{System requirements}
+
+Nothing in particular. Flow is in very plain C and should be portable to
+pretty much anything without alteration. Check beginning of file for defines
+if it gives trouble.
+
+\headB{Distribution and Bug Reports}
+
+Flow is free software covered by the GPL. See the file \verb+COPYING+
+for details. Email to \verb+terry_n_brown@yahoo.com+ with bug reports
+etc.
+
+\newpage
+\headB{Flowchart description syntax}
+
+\verb+[indented text]+ indicates the command accepts zero or more line of
+text, these lines are identified by indentation. All lines after the command
+starting with either a space or a tab are assumed to be text for that
+command. The first line not starting with one of these characters is assumed
+to be the next command. Distributed code / executeables are case
+insensitive, but local compilations may vary.
+
+The flowchart is always ``going'' either up, down, left or right. The
+initial direction is down.
+
+The flowchart description file is terminated either by an invalid command,
+a blank line, or the end of the file. Keywords are case sensitive.
+
+% This bit became redundant with v 0.99
+%
+%% The output from flow should appear inside a \LaTeX\ picture environment.
+%% Use
+%%
+%% \pushin\verb+\begin{picture}(x,y)(0,-y)+
+%%
+%% to start the environment (as the flow
+%% chart starts at 0,0 and normally goes down, this put the pictures origin at
+%% the top left corner). 10 and 10 are ok as initial values for x and y. The
+%% positioning of the picture can be adjusted with the second pair as usual for
+%% the picture environment.
+
+The output from flow will appear inside a \LaTeX\ picture environment.
+The positioning of the picture can be adjusted with the second pair as usual
+for the picture environment.
+
+\verb+\unitlength+ should be set for use with the picture environment, all
+the examples in this document use \verb+2em+ (ie. put
+\verb+\setlength{\unitlength}{2em}+ at the top of the \LaTeX\ file).
+Smaller values make the boxes tighter around the text, larger values make
+them more open.
+
+\headC{The commands}
+
+\verb_% comment to end of line_
+
+If the first thing on a line is a '\verb_%_' symbol the line is
+treated as a comment. Thanks to Joost Bruynooghe for adding this command.
+
+\begin{verbatim}
+Box [x y]
+ [indented text]
+\end{verbatim}
+
+Draws a text at the current position, including a line or arrow leading to it
+if appropriate. If x and y are specified, the size of the box (in
+\verb+\unitlength+s), and all subsequent boxes, is set to these. The
+default size of a box is 4 by 2 \verb+\unitlength+s.
+
+{\small
+\begin{verbatim}
+Right
+Box
+ This is
+ the first
+ box.
+Box 8 1
+ And this is the second
+\end{verbatim}
+}
+
+\begin{picture}(10,2)(0,-2)
+% picture environment flowchart generated by flow 0.95
+\put(0.0000,-2.0000){\framebox(4.0000,2.0000)[c]{\shortstack[c]{
+This is \\
+the first \\
+box.
+}}}
+\put(4.0000,-1.0000){\vector(1,0){1.0000}}
+\put(5.0000,-1.5000){\framebox(8.0000,1.0000)[c]{\shortstack[c]{
+And this is the second
+}}}
+\end{picture}
+
+\newpage
+\begin{verbatim}
+Oval [x y]
+ [indented text]
+
+Tilt [x y]
+ [indented text]
+
+Text [x y]
+ [indented text]
+\end{verbatim}
+
+\verb+Oval+, \verb+Tilt+ and \verb+Text+ are identical to \verb+Box+, except
+for the shape of the frame. (\verb+Text+ is an invisible frame.)
+
+{\small
+\begin{verbatim}
+Right
+Oval
+ This is
+ an Oval
+Tilt
+ And this
+ is a
+ Tilt
+Text
+ And this
+ is a
+ Text
+\end{verbatim}
+}
+
+\begin{picture}(10,3)(0,-3)
+% picture environment flowchart generated by flow 0.95
+\put(2.0000,-1.0000){\oval(4.0000,2.0000)}
+\put(0.0000,-2.0000){\makebox(4.0000,2.0000)[c]{\shortstack[c]{
+This is \\
+an Oval
+}}}
+\put(4.0000,-1.0000){\vector(1,0){1.0000}}
+\put(5.0000,-2.0000){\makebox(4.0000,2.0000)[c]{\shortstack[c]{
+And this \\
+is a \\
+Tilt
+}}}
+\put(5.3333,0.0000){\line(1,0){4.0000}}
+\put(4.6667,-2.0000){\line(1,0){4.0000}}
+\put(4.6667,-2.0000){\line(1,3){0.6667}}
+\put(8.6667,-2.0000){\line(1,3){0.6667}}
+\put(9.0000,-1.0000){\vector(1,0){1.0000}}
+\put(10.0000,-2.0000){\makebox(4.0000,2.0000)[c]{\shortstack[c]{
+And this \\
+is a \\
+Text
+}}}
+\end{picture}
+
+\begin{verbatim}
+Choice A B C D [x y]
+ [indented text]
+\end{verbatim}
+
+Draws a choice diamond, with the corners labeled as illustrated by the left
+diamond in the example. Periods (.) are not printed. The optional x an y
+parameters alter the size of the choice. The default size is 4 by 4
+\verb+\unitlengh+s. Flow will report an error for non-square choice boxes
+whose aspect ratio doesn't match one of the line slopes supported by \LaTeX\
+(-6 -- 6 : -6 -- 6, integers only).
+
+{\small
+\begin{verbatim}
+Right
+Choice A B C D
+ Label
+ any
+ corner
+Choice Yes . No .
+ Normally
+ only two.
+\end{verbatim}
+}
+
+\begin{picture}(10,5)(0,-5)
+% picture environment flowchart generated by flow 0.95
+\put(0.0000,-2.0000){\line(1,1){2.0000}}
+\put(0.0000,-2.0000){\line(1,-1){2.0000}}
+\put(4.0000,-2.0000){\line(-1,-1){2.0000}}
+\put(4.0000,-2.0000){\line(-1,1){2.0000}}
+\put(0.0000,-4.0000){\makebox(4.0000,4.0000)[c]{\shortstack[c]{
+Label\\
+any\\
+corner
+}}}
+\put(2.6000,0.0000){\makebox(0,0)[lt]{A}}
+\put(0.0000,-1.4000){\makebox(0,0)[rt]{B}}
+\put(4.0000,-1.4000){\makebox(0,0)[lt]{C}}
+\put(2.6000,-4.0000){\makebox(0,0)[lb]{D}}
+\put(4.0000,-2.0000){\vector(1,0){1.0000}}
+\put(5.0000,-2.0000){\line(1,1){2.0000}}
+\put(5.0000,-2.0000){\line(1,-1){2.0000}}
+\put(9.0000,-2.0000){\line(-1,-1){2.0000}}
+\put(9.0000,-2.0000){\line(-1,1){2.0000}}
+\put(5.0000,-4.0000){\makebox(4.0000,4.0000)[c]{\shortstack[c]{
+Normally\\
+only two.
+}}}
+\put(7.6000,0.0000){\makebox(0,0)[lt]{Yes}}
+\put(9.0000,-1.4000){\makebox(0,0)[lt]{No}}
+\end{picture}
+
+\verb+SetTrack none | arrow | line+
+
+Use arrows, lines, or nothing for drawing connections between boxes.
+
+\verb+TxtPos P1 P2 [B [A]]+
+
+\verb+P1+ is the \LaTeX\ position specification (eg. [c] or [l]) for the
+lines of text that makes up the blocks of text in the boxes, \verb+P2+ is
+the \LaTeX\ position specification for the whole block of text within the
+box. \verb+B+ is the string (no white space) to be placed before each line
+of text, \verb+A+ is the string to be placed after each line of text. The
+example shows the use of \verb+B+ to keep text off the edge of the box.
+
+{\small
+\begin{verbatim}
+Right
+SetTrack arrow
+TxtPos [l] [l]
+Box 3.5 2
+ Needs some
+ space on the
+ left
+TxtPos [l] [l] ~
+Box
+ Left justified
+ text with
+ space
+SetTrack line
+TxtPos [c] [c]
+Box
+ Centred
+ Text
+SetTrack none
+TxtPos [r] [r] ~ \hspace*{1ex}
+Box
+ Right justified
+ Text
+\end{verbatim}
+}
+
+\begin{picture}(10,3)(0,-2.5)
+% picture environment flowchart generated by flow 0.95
+\put(0.0000,-2.0000){\framebox(3.5000,2.0000)[l]{\shortstack[l]{
+Needs some\\
+space on the\\
+left
+}}}
+\put(3.5000,-1.0000){\vector(1,0){1.0000}}
+\put(4.5000,-2.0000){\framebox(3.5000,2.0000)[l]{\shortstack[l]{
+~Left justified\\
+~text with\\
+~space
+}}}
+\put(8.0000,-1.0000){\line(1,0){1.0000}}
+\put(9.0000,-2.0000){\framebox(3.5000,2.0000)[c]{\shortstack[c]{
+Centred\\
+Text
+}}}
+\put(13.5000,-2.0000){\framebox(3.5000,2.0000)[r]{\shortstack[r]{
+~Right justified\hspace*{1ex}\\
+~Text\hspace*{1ex}
+}}}
+\end{picture}
+
+\newpage
+\verb+Tag+
+
+\verb+ToTag+
+
+\verb+Tag+ stores the location and size of the last object drawn on a stack,
+\verb+ToTag+ returns to that position (removing the item from the stack). This is
+particularly useful with \verb+Choice+s, allowing a second chain to be built
+from the diamond, but it can be used with any other item. Flow will complain
+if it encounters more \verb+ToTag+s the \verb+Tag+s, but won't mention
+\verb+Tag+s left on the stack when it finishes.
+
+{\small
+\begin{verbatim}
+Right 0
+Choice . . N Y
+ Ready to
+ stop?
+Tag
+Choice . . Right Down
+ Go right
+ or Down?
+Tag
+Right 1
+Box
+ To the
+ right
+ToTag
+Down
+Box
+ Down here
+ToTag
+Down
+Oval
+ STOP
+\end{verbatim}
+}
+
+\begin{picture}(10,7)(0,-5)
+% picture environment flowchart generated by flow 0.95
+\put(0.0000,0.0000){\line(1,0){0.0000}}
+\put(0.0000,0.0000){\vector(1,0){1.0000}}
+\put(1.0000,0.0000){\line(1,1){2.0000}}
+\put(1.0000,0.0000){\line(1,-1){2.0000}}
+\put(5.0000,0.0000){\line(-1,-1){2.0000}}
+\put(5.0000,0.0000){\line(-1,1){2.0000}}
+\put(1.0000,-2.0000){\makebox(4.0000,4.0000)[c]{\shortstack[c]{
+Ready to\\
+stop?
+}}}
+\put(5.0000,0.6000){\makebox(0,0)[lt]{N}}
+\put(3.6000,-2.0000){\makebox(0,0)[lb]{Y}}
+\put(5.0000,0.0000){\vector(1,0){1.0000}}
+\put(6.0000,0.0000){\line(1,1){2.0000}}
+\put(6.0000,0.0000){\line(1,-1){2.0000}}
+\put(10.0000,0.0000){\line(-1,-1){2.0000}}
+\put(10.0000,0.0000){\line(-1,1){2.0000}}
+\put(6.0000,-2.0000){\makebox(4.0000,4.0000)[c]{\shortstack[c]{
+Go right\\
+or Down?
+}}}
+\put(10.0000,0.6000){\makebox(0,0)[lt]{Right}}
+\put(8.6000,-2.0000){\makebox(0,0)[lb]{Down}}
+\put(10.0000,0.0000){\line(1,0){1.0000}}
+\put(11.0000,0.0000){\vector(1,0){1.0000}}
+\put(12.0000,-1.0000){\framebox(4.0000,2.0000)[c]{\shortstack[c]{
+To the\\
+right
+}}}
+\put(8.0000,-2.0000){\vector(0,-1){1.0000}}
+\put(6.0000,-5.0000){\framebox(4.0000,2.0000)[c]{\shortstack[c]{
+Down here
+}}}
+\put(3.0000,-2.0000){\vector(0,-1){1.0000}}
+\put(3.0000,-4.0000){\oval(4.0000,2.0000)}
+\put(1.0000,-5.0000){\makebox(4.0000,2.0000)[c]{\shortstack[c]{
+STOP
+}}}
+\end{picture}
+
+\newpage
+\begin{verbatim}
+Up [d [*]]
+Down [d [*]]
+Left [d [*]]
+Right [d [*]]
+\end{verbatim}
+
+With or without the optional parameter, these command change the current
+direction of the flowchart. With the optional parameter, they draw a line,
+if \verb+SetTrack+ is \verb+line+ {\em or\/} \verb+arrow+, or leave a gap, if
+\verb+SetTrack+ in \verb+none+. The length of the line (or gap) is $d$. By
+default \verb+Box+es, \verb+Oval+s, \verb+Tilt+s and \verb+Text+s are 4 units
+wide and 2 units high. A \verb+Choice+ is 4 by 4 units. The arrows that
+connect things together are 1 unit. So a box drawn while the current
+direction is down would occupy 2 + 1 = 3 vertical units.
+
+To force the line to end in a arrow head, use the ``*'', which must be
+separated from the ``d'' by a space.
+
+{\small
+\begin{verbatim}
+Right 1
+Box
+ Flowing
+ along.
+Right 1
+Tag
+Down 2
+Left 6
+Up 2 *
+ToTag
+Right 3
+Down
+Oval
+ STOP
+\end{verbatim}
+}
+
+\begin{picture}(10,4)(0,-3)
+% picture environment flowchart generated by flow 0.95
+\put(0.0000,0.0000){\line(1,0){1.0000}}
+\put(1.0000,0.0000){\vector(1,0){1.0000}}
+\put(2.0000,-1.0000){\framebox(4.0000,2.0000)[c]{\shortstack[c]{
+Flowing \\
+along.
+}}}
+\put(6.0000,0.0000){\line(1,0){1.0000}}
+\put(7.0000,0.0000){\line(0,-1){2.0000}}
+\put(7.0000,-2.0000){\line(-1,0){6.0000}}
+\put(1.0000,-2.0000){\vector(0,1){2.0000}}
+\put(7.0000,0.0000){\line(1,0){3.0000}}
+\put(10.0000,0.0000){\vector(0,-1){1.0000}}
+\put(10.0000,-2.0000){\oval(4.0000,2.0000)}
+\put(8.0000,-3.0000){\makebox(4.0000,2.0000)[c]{\shortstack[c]{
+STOP
+}}}
+\end{picture}
+
+\verb+Scale x y+
+
+Scale the {\em next\/} item by the specified values
+
+{\small
+\begin{verbatim}
+Right
+Oval
+ Normal
+ Oval
+Scale 2 1
+Box
+ A smaller oval is a better stop
+Scale 0.5 0.5
+Oval
+ STOP
+\end{verbatim}
+}
+
+\begin{picture}(10,3)(0,-3)
+% picture environment flowchart generated by flow 0.95
+\put(2.0000,-1.0000){\oval(4.0000,2.0000)}
+\put(0.0000,-2.0000){\makebox(4.0000,2.0000)[c]{\shortstack[c]{
+Normal\\
+Oval
+}}}
+\put(4.0000,-1.0000){\vector(1,0){1.0000}}
+\put(5.0000,-2.0000){\framebox(8.0000,2.0000)[c]{\shortstack[c]{
+A smaller oval is a better stop
+}}}
+\put(13.0000,-1.0000){\vector(1,0){1.0000}}
+\put(15.0000,-1.0000){\oval(2.0000,1.0000)}
+\put(14.0000,-1.5000){\makebox(2.0000,1.0000)[c]{\shortstack[c]{
+STOP
+}}}
+\end{picture}
+
+\begin{verbatim}
+Skip x0 y0 x1 x1
+\end{verbatim}
+
+\begin{tabular}{r@{~~}p{4in}}
+\tt x0 & Horizontal separation between boxes, default 1 \verb+\unitlength+ \\
+\tt y0 & Vertical separation between boxes, default 1 \verb+\unitlength+ \\
+\tt x1 & Multiplier for \verb+Left+ and \verb+Right+ commands, default 1 \\
+\tt y1 & Multiplier for \verb+Up+ and \verb+Down+ commands, default 1 \\
+\end{tabular}
+
+{\small
+\begin{verbatim}
+Skip 0 0 1 1
+SetTrack none
+Box
+ After this
+ Box
+Box
+ Is another
+ with no
+ gap
+SetTrack arrow
+Right 5
+Up 1 *
+Left 1 *
+Down 1 *
+Right 1 *
+Skip 0 0 3 3
+Up 1 *
+Left 1 *
+Down 1 *
+Right 1 *
+\end{verbatim}
+}
+
+\begin{picture}(10,5)(0,-5)
+% picture environment flowchart generated by flow 0.95
+\put(0.0000,-2.0000){\framebox(4.0000,2.0000)[c]{\shortstack[c]{
+After this\\
+Box
+}}}
+\put(0.0000,-4.0000){\framebox(4.0000,2.0000)[c]{\shortstack[c]{
+Is another\\
+with no\\
+gap
+}}}
+\put(4.0000,-3.0000){\line(1,0){5.0000}}
+\put(9.0000,-3.0000){\vector(0,1){1.0000}}
+\put(9.0000,-2.0000){\vector(-1,0){1.0000}}
+\put(8.0000,-2.0000){\vector(0,-1){1.0000}}
+\put(8.0000,-3.0000){\vector(1,0){1.0000}}
+\put(9.0000,-3.0000){\vector(0,1){3.0000}}
+\put(9.0000,0.0000){\vector(-1,0){3.0000}}
+\put(6.0000,0.0000){\vector(0,-1){3.0000}}
+\put(6.0000,-3.0000){\vector(1,0){3.0000}}
+\end{picture}
+
+\newpage
+\headB{VMS notes}
+
+I don't know much VMS, but this is one way of getting it to work. Compile
+and link as normal, then
+
+{\tt flow :== \$\fbox{\$1\$DIA3:}[brownt1.usr.flow]flow.exe}
+
+where the bit in the box is the name of the drive you're working on, and
+\verb+[brownt1.usr.flow]+ is the appropriate path. Then use the
+
+\verb+flow infile outfile+
+
+form, as the redirection form doesn't seem to work.
+
+\newpage
+\headB{An example}
+
+The instructions that generated this flow chart are included in
+a commented section in \verb+flowdoc.tex+. Note the block of text is part of
+the picture environment (a \verb+Text+).
+
+% THIS IS THE FLOW DATA FOR THE EXAMPLE AT THE END
+% Box
+% Initialise
+% st
+% Oval
+% Begin
+% RootParse
+% Tag
+% Box
+% Initialise
+% A \& B
+% Down 1
+% Box
+% Call client
+% with A, B \& st
+% Choice . . Y N
+% Is B a
+% New-Root
+% Node?
+% Tag
+% Down 1
+% Choice . . Y N
+% Is B a
+% Fungi
+% Node?
+% Tag
+% Down 1
+% Choice . N . Y
+% Is B the
+% Current-End
+% Node?
+% Tag
+% Oval
+% Return
+% ToTag
+% Left 3
+% Up 2
+% Box
+% Update
+% direction
+% data in st
+% Box
+% A = B
+% B = B.next
+% Up 10
+% Right 5 *
+% ToTag
+% Right 1
+% Box
+% Adjust fungi
+% values in st
+% Down 2
+% Left 6 *
+% ToTag
+% Right
+% Box
+% Increment
+% st order
+% Tilt
+% Recursively
+% call RootParse
+% Box
+% Decrement
+% st order
+% Down 2
+% Left 15 *
+% ToTag
+% SetTrack none
+% Down 2
+% Right 8
+% TxtPos [l] [c]
+% Text
+% A and B are the node records at the
+% start and end of the internode being
+% processed. `st' is a record containing
+% information about the current fungal
+% population, position in 3-space, root
+% order etc. It is cloned during the
+% recursive descent.
+
+\scriptsize
+\setlength{\unitlength}{1.8em}
+%% start of flow output
+\begin{picture}(24.000000,32.000000)(-5.000000,-32.000000)
+% picture environment flowchart generated by flow 0.99e
+\put(0.0000,-2.0000){\framebox(4.0000,2.0000)[c]{\shortstack[c]{
+Initialise\\
+st
+}}}
+\put(2.0000,-2.0000){\vector(0,-1){1.0000}}
+\put(2.0000,-4.0000){\oval(4.0000,2.0000)}
+\put(0.0000,-5.0000){\makebox(4.0000,2.0000)[c]{\shortstack[c]{
+Begin\\
+RootParse
+}}}
+\put(2.0000,-5.0000){\vector(0,-1){1.0000}}
+\put(0.0000,-8.0000){\framebox(4.0000,2.0000)[c]{\shortstack[c]{
+Initialise\\
+A \& B
+}}}
+\put(2.0000,-8.0000){\line(0,-1){1.0000}}
+\put(2.0000,-9.0000){\vector(0,-1){1.0000}}
+\put(0.0000,-12.0000){\framebox(4.0000,2.0000)[c]{\shortstack[c]{
+Call client\\
+with A, B \& st
+}}}
+\put(2.0000,-12.0000){\vector(0,-1){1.0000}}
+\put(0.0000,-15.0000){\line(1,1){2.0000}}
+\put(0.0000,-15.0000){\line(1,-1){2.0000}}
+\put(4.0000,-15.0000){\line(-1,-1){2.0000}}
+\put(4.0000,-15.0000){\line(-1,1){2.0000}}
+\put(0.0000,-17.0000){\makebox(4.0000,4.0000)[c]{\shortstack[c]{
+Is B a\\
+New-Root\\
+Node?
+}}}
+\put(4.0000,-14.4000){\makebox(0,0)[lt]{Y}}
+\put(2.6000,-17.0000){\makebox(0,0)[lb]{N}}
+\put(2.0000,-17.0000){\line(0,-1){1.0000}}
+\put(2.0000,-18.0000){\vector(0,-1){1.0000}}
+\put(0.0000,-21.0000){\line(1,1){2.0000}}
+\put(0.0000,-21.0000){\line(1,-1){2.0000}}
+\put(4.0000,-21.0000){\line(-1,-1){2.0000}}
+\put(4.0000,-21.0000){\line(-1,1){2.0000}}
+\put(0.0000,-23.0000){\makebox(4.0000,4.0000)[c]{\shortstack[c]{
+Is B a\\
+Fungi\\
+Node?
+}}}
+\put(4.0000,-20.4000){\makebox(0,0)[lt]{Y}}
+\put(2.6000,-23.0000){\makebox(0,0)[lb]{N}}
+\put(2.0000,-23.0000){\line(0,-1){1.0000}}
+\put(2.0000,-24.0000){\vector(0,-1){1.0000}}
+\put(0.0000,-27.0000){\line(1,1){2.0000}}
+\put(0.0000,-27.0000){\line(1,-1){2.0000}}
+\put(4.0000,-27.0000){\line(-1,-1){2.0000}}
+\put(4.0000,-27.0000){\line(-1,1){2.0000}}
+\put(0.0000,-29.0000){\makebox(4.0000,4.0000)[c]{\shortstack[c]{
+Is B the\\
+Current-End\\
+Node?
+}}}
+\put(0.0000,-26.4000){\makebox(0,0)[rt]{N}}
+\put(2.6000,-29.0000){\makebox(0,0)[lb]{Y}}
+\put(2.0000,-29.0000){\vector(0,-1){1.0000}}
+\put(2.0000,-31.0000){\oval(4.0000,2.0000)}
+\put(0.0000,-32.0000){\makebox(4.0000,2.0000)[c]{\shortstack[c]{
+Return
+}}}
+\put(0.0000,-27.0000){\line(-1,0){3.0000}}
+\put(-3.0000,-27.0000){\line(0,1){2.0000}}
+\put(-3.0000,-25.0000){\vector(0,1){1.0000}}
+\put(-5.0000,-24.0000){\framebox(4.0000,2.0000)[c]{\shortstack[c]{
+Update\\
+direction\\
+data in st
+}}}
+\put(-3.0000,-22.0000){\vector(0,1){1.0000}}
+\put(-5.0000,-21.0000){\framebox(4.0000,2.0000)[c]{\shortstack[c]{
+A = B\\
+B = B.next
+}}}
+\put(-3.0000,-19.0000){\line(0,1){10.0000}}
+\put(-3.0000,-9.0000){\vector(1,0){5.0000}}
+\put(4.0000,-21.0000){\line(1,0){1.0000}}
+\put(5.0000,-21.0000){\vector(1,0){1.0000}}
+\put(6.0000,-22.0000){\framebox(4.0000,2.0000)[c]{\shortstack[c]{
+Adjust fungi\\
+values in st
+}}}
+\put(8.0000,-22.0000){\line(0,-1){2.0000}}
+\put(8.0000,-24.0000){\vector(-1,0){6.0000}}
+\put(4.0000,-15.0000){\vector(1,0){1.0000}}
+\put(5.0000,-16.0000){\framebox(4.0000,2.0000)[c]{\shortstack[c]{
+Increment\\
+st order
+}}}
+\put(9.0000,-15.0000){\vector(1,0){1.0000}}
+\put(10.0000,-16.0000){\makebox(4.0000,2.0000)[c]{\shortstack[c]{
+Recursively\\
+call RootParse
+}}}
+\put(10.3333,-14.0000){\line(1,0){4.0000}}
+\put(9.6667,-16.0000){\line(1,0){4.0000}}
+\put(9.6667,-16.0000){\line(1,3){0.6667}}
+\put(13.6667,-16.0000){\line(1,3){0.6667}}
+\put(14.0000,-15.0000){\vector(1,0){1.0000}}
+\put(15.0000,-16.0000){\framebox(4.0000,2.0000)[c]{\shortstack[c]{
+Decrement\\
+st order
+}}}
+\put(17.0000,-16.0000){\line(0,-1){2.0000}}
+\put(17.0000,-18.0000){\vector(-1,0){15.0000}}
+\put(11.0000,-8.0000){\makebox(4.0000,2.0000)[c]{\shortstack[l]{
+A and B are the node records at the\\
+start and end of the internode being\\
+processed. `st' is a record containing\\
+information about the current fungal\\
+population, position in 3-space, root \\
+order etc. It is cloned during the \\
+recursive descent.
+}}}
+\end{picture}
+
+%% end of flow output
+
+\end{document}