diff options
author | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
commit | e0c6872cf40896c7be36b11dcc744620f10adf1d (patch) | |
tree | 60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/flow |
Initial commit
Diffstat (limited to 'support/flow')
-rw-r--r-- | support/flow/COPYING | 340 | ||||
-rw-r--r-- | support/flow/README | 38 | ||||
-rw-r--r-- | support/flow/flow.c | 846 | ||||
-rw-r--r-- | support/flow/flowdoc.pdf | bin | 0 -> 104345 bytes | |||
-rw-r--r-- | support/flow/flowdoc.tex | 783 |
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 Binary files differnew file mode 100644 index 0000000000..43e4d2a8c0 --- /dev/null +++ b/support/flow/flowdoc.pdf 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} |