home *** CD-ROM | disk | FTP | other *** search
-
- TSNIP - this is my own implementation of "cutting" text from _any_
- window. I understand there is another program available to do
- the same thing; therefore I will do a better job on this than
- if there wasn't :-). BTW, I've finally seen the program which
- inspired TSnip (by reputation), but I find TSnip in its
- current incarnation far more useful.
-
- Usage: tsnip [-p] [-c] [-s] [-k] [-K] [-a] [-m] [-e] [x_offset y_offset]
- [-f <font>] [-o <filename>] [on <screenname> or on -null]
- [-z or -vt100] [-emacs or -vi]
-
- Or click on its icon from the Workbench, after customizing the tooltypes
- field if you like. See the Workbench support section for the details on
- that.
-
- Whew!
-
- 0. Intro.
- 1. Output Destination.
- 2. Command line options.
- 3. Workbench Support.
- 4. Interaction (keyboard/mouse control).
- 5. Where the TSnip window opens.
- 6. What to do with the PIPE: file.
- 7. Problem windows.
- 8. Handler-commands file.
- 9. Control panel.
- 10. Syntax & Examples.
- 11. Added bonus for users of the 'vi' and 'emacs' editors.
- 12. Credits.
-
-
- 0. Intro.
-
- Note the new name... this is to avoid confusion with Digital Dynamics'
- signal-processing program Snip. I now refer to the whole group of
- programs in the distribution as CATSnip (Computer Aided Text Snip)
- and this program as TSnip (Text Snip). How do you pronounce TSnip?
- You could pronounce it like you do T-bone, or with a silent T. Just so long
- as you know which is which.
-
- Copyright 1988 John Russell Freely redistributable
-
- If you found the old Snip even marginally useful, you'll find TSnip V1.4
- ten times better! If you had no use whatsoever for the old Snip but you
- do use vi, either over a terminal program or as the Manx Z editor, you'll
- get a lot better use from your editor if you run it in conjunction with
- TSnip. This version, V1.4a, includes support for the emacs editor in
- addition to vi.
-
- The latest version (1.4a) has proven to be so much more useful than 1.3
- that I'd be remiss not to encourage small donations ($5 or $10) if you're
- so inclined :-).
-
- John Russell
- 5 Alderdice Place
- St. John's, Newfoundland
- Canada A1B 2P8
- (709) 726-7847
-
- E-mail: john13@garfield.uucp (...utai!garfield!john13)
-
- Features:
- - area to be cut is outlined during cutting
- - text in target area prevented from scrolling while cut going on
- - for non-standard windows, you can tweak placement of the 8x8
- regions with command line arguments or via key commands
- - multiple save formats; the layout of the program makes it simple
- to add in your own if it isn't supported
- - recognize text in any colour, or combination of colours
- - recognize any 8x8 font; you must create special files using
- TSnipGen for fonts other than the default Topaz 8 (see docs for
- that program for more details)
- - control panel for mouse interaction, step-by-step explanations,
- and changing options
- - can operate on any screen, and move from one screen to another
- - co-operates with mouse handler programs like DMouse
- - startable from CLI or Workbench; options can all be specified for
- either environment
- - comes with source, support programs, and a selection of fonts
- - supports CLI "break" command for termination
-
- - enhances the functionality of vi or emacs if you use either of those
- editors
-
- Currently supported:
- - print text to standard output
- - standard output sent to any file
- - change output file at any time
- - save text to PIPE: file
- - save text to clipboard
- - have text echoed as if typed
- - with carriage returns after each line
- - as one long unbroken line
-
- TSnip is a program I wrote for three reasons:
-
- 1) I needed something like it.
- 2) I had heard there was a program to do it and wondered how it would be
- possible to "read" text from a window, since once the letters are plotted
- there's no record of them anywhere except as pixels on the screen.
- 3) As a spinoff of some of the ideas I had in writing TSnip the vi-controller
- was started as a seperate program. I've decided to incorporate it into
- this and future versions of TSnip since it only adds about 1.5k.
-
- Using TSnip
- -----------
-
- 1. Output Destination
-
- The main consideration when using TSnip is deciding how you want the text
- you "cut" from a window to be saved. Since I couldn't find any one way which
- was good enough for all cases, I allowed 5 alternatives, and made it
- possible to switch between them at any time.
-
- Print to standard output - this is the default if you don't specify anything
- else from the CLI. If you want to direct output to a file, use this mode
- along with the -o option, instead of using ">file" redirection. In this
- mode, multiple writes can be done to a single file which is closed when
- the program exits. All error messages are also sent to standard output.
-
- Write to pipe: file - I don't know about anyone else, but I find a pipe
- facility very useful; I imagine it's also very under-used, so if you
- don't have either of the two PD or one commercial implementations
- available I advise you to look into getting one. Basically a pipe is a
- file you can read and write simultaneously. Only some small amount of
- space is used at a time (typically 4K) so you can send a 500K output
- file from one program as input to another program without ever having
- to save anything to disk. Once the last of the data has been read, the
- file disappears. Thus any editor or other program that accepts straight
- ASCII input can process text you save to a pipe.
-
- NB: V1.4 corrects a bug which sent a null character at the end of each line
- of output to a pipe or stdout file and caused problems for some programs
- (like DME) that don't like nulls in their text.
-
- Paste to Clipboard - this is another under-used feature of the Amiga, sadly
- most editors don't use the clipboard for their cut and paste buffers.
- If they did you would be able to cut a section of text in, say,
- AmigaBasic, and paste it into another editor, or vice versa. Complete
- interchangeability, in the same vein as IFF.
-
- NB: I've implemented the clipboard section, however aside from verifying that
- the data is written and seems to be in correct format I don't know of
- anything I have that will read it, so that part can't be tested.
-
- Keyboard - the program which inspired this one (if only by reputation) pastes
- its data this way, by fooling your computer into thinking you had re-
- typed the text you snipped. This is extremely useful, so I implemented it
- for V1.2. I also give two different sub-options here... you can have the
- text printed as a column, eg line1 <cr> line2 <cr> etc, or as one long
- line. The first example allows you to import a section of text unaltered
- into something like a word-processor, the second allows you to do
- something like type 'delete' and snip a bunch of filenames which will be
- pasted back into the command line. When either of these output modes are
- selected, the next window to be activated after some text is cut will
- receive the text. If you want to make multiple snips in this mode, the
- -a option may be handy, it prevents you from having to manually click on
- the TSnip window after each paste operation. The keyboard option with
- carriage returns is the default if you start TSnip from the Workbench
- and don't specify a different paste method in the icon tooltypes.
-
-
- 2. Command line options.
-
- TSnip features about a gazillion command line options. As new features
- get added I'm sure more will follow. To get the most from the program you
- will need to know what they all do. Nearly all of them can be turned on or
- off from within the program itself, but once you know how you want the
- program to operate it's faster to do all the setup as you run it (especially
- if you define an alias within a shell to run it with all your favourite
- options).
-
- Output
- ------
-
- -s: output text goes to standard output, which is the CLI window or
- a file like PRT: or RAM:file. Under the 1.3 system software you
- can use the SPEAK: device as the destination to have the text
- read to you from the screen!
-
- -c: output text goes to the clipboard
-
- -p: output text goes to the file PIPE:tsnip (requires the pipe: device)
-
- -k: output text goes, as if typed, into the next window to be
- activated; each line is terminated by a return
-
- -K: output text is handled identically to -k except it is pasted as
- one long line using spaces instead of returns
-
- Window Activation
- -----------------
-
- -a: when output is going to keyboard, re-activate the TSnip window
- after each paste finishes
-
- -m: co-operate with a mouse handler, like DMouse or QMouse; when the
- TSnip window is activated or deactivated a command will be executed
- to change the options for the handler, so that you can have auto-
- activation of windows disabled only while it's necessary for TSnip
- to function. The file handler-commands in your S: directory holds
- the two commands which change these options.
-
- Offsets
- -------
-
- any two numbers: these will be taken as an offset to be used in
- positioning the text-recognition box; negative numbers should
- be preceded by a negative sign, positive numbers don't need a
- sign. TSnip by default recognizes text which is positioned in
- windows at the same position as used by console windows. However
- programs that don't use the console can plot text at any pixel
- position they like (for instance VT100 plots text at an offset
- of 0 & -1 from the default). If you don't know the offset
- beforehand you can find it by trial and error while TSnip is
- running; see the section on interaction for details on that.
-
- Editor control
- --------------
-
- -e: go straight into editor mode; instead of cutting text TSnip will
- let you use the mouse for cursor positioning in an editor which
- doesn't already use the mouse
-
- -vi: set up TSnip to send vi cursor-position commands; doesn't set
- editor mode automatically
-
- -emacs: TSnip will send emacs cursor-position commands while in editor
- mode
-
- -z: use this option if you are using the Aztec Z editor (a vi clone);
- it corrects a bug in Z's positioning commands. This option sets
- the -vi option too.
-
- -vt100: if you will be doing your editing in VT100 this sets the right
- offsets for doing cursor positioning in that window
-
- NB: The -vi, -emacs, -z and -vt100 options are "hints" to TSnip. You
- should use whatever combination best applies to you, for instance
- I always use -vi and -vt100... even if I don't expect to need to
- use the edit-control mode.
-
- Miscellaneous
- -------------
-
- -f <fontname>: recognize text in a particular font; you must use
- TSnipGen to create a bitmap file for that font, and put the
- bitmap file (with a .fontdef extension) in your S: directory.
-
- -o <filename>: text which is pasted to standard output will be directed
- into the named file. This could be a disk file, or the printer,
- or to any other more permanent storage spot than the CLI window.
-
- on <screenname>: open the TSnip window on the named screen; the details
- of this process, such as dealing with screens that have no title,
- are covered later on in this document.
-
-
- 3. Workbench Support.
-
- This version is the first to support the Workbench. When you run TSnip
- from its icon, without any tooltypes set up, it's the equivalent of
- running: "tsnip -k -a" (since standard output isn't too useful from the
- Workbench unless you specify an output file).
-
- All command line options may be specified via the tooltypes field of
- the icon, and all are optional. The way to make TSnip recognize your
- favourite set of options is to single click on the TSnip icon, select
- the "Info" menu item of Workbench, and when the Info window opens press the
- button marked "add" and type into the corresponding string gadget a line of
- the form "KEYWORD=OPTION" for each option you wish to set.
-
- The options supported are:
-
- FILE=output filename for pasting to stdout
- PASTE=STDOUT, CLIP, PIPE, KEY, or KEYNOCR
- REACTIVATE=TRUE or FALSE
- MOUSECONTROL=TRUE or FALSE
- FONT=fontname
- SCREEN=screenname or "-null" if the screen is untitled
- XOFFSET=offset value
- YOFFSET=offset value
- EDITMODE=TRUE or FALSE
- EDITWINDOW=z or vt100
- EDITOR=vi or emacs
-
- Notes - If you specify one offset the other must be given too.
- The fontname is given as for instance "topaz" or "pearl", no ".font".
-
-
- 4. Interaction (keyboard/mouse control).
-
- When the TSnip window is active, the RIGHT mouse button can be used to
- outline a rectangular area of text within whichever window the mouse is
- currently over. After the text of the area has been interpreted the area
- will flash to let you know it is done. While you are operating on the window
- it will not change (eg scroll).
-
- When the special edit mode is enabled, the right button is used to
- position the cursor within an editor that doesn't have mouse control. You
- can tell when edit mode is turned on by looking at the TSnip window's
- title which changes to reflect the mode. In edit mode, you click the
- right mouse button once directly over the cursor's current position and
- once over the desired new position. TSnip then sends the proper keystrokes
- to the window to move the cursor there. Editors currently supported are
- vi and emacs.
-
- Most command-line options can be changed by using the keyboard while TSnip
- is the active window. The current key commands are:
-
- - s: change output destination to standard output (usually the CLI
- window)
- - p: direct output to the file pipe:tsnip
- - c: direct output to the clipboard
- - k: direct output to the keyboard
- - K: same as k except text is pasted as one long line
-
- - a: toggle automatic window activation when k/K selected
-
- - u: move the expected location of characters in a window UP by 1 pixel
- - d: move the expected location of characters in a window DOWN 1 pixel
- - l: move the expected location of characters in a window LEFT 1 pixel
- - r: move the expected location of characters in a window RIGHT 1 pixel
- - <return>: reset the offset back to (0,0), the default for console
- windows
-
- NB: while in edit mode, toggled by the e key, the above 5 keys affect the
- position at which TSnip considers a row or column to start. That is
- there is a seperate 'cursor position' offset in addition to the one
- used for the text recognition box.
-
- - q: print the colour (as pen #) of the pixel directly below the mouse.
- Mnemonic is "query". Useful for diagnosing problems in windows.
-
- - <space>: close one or both TSnip windows and re-open them on the next
- screen down. Brings that screen to the front.
-
- - m: issue commands to enable or disable mouse handler programs when the
- TSnip window becomes active or inactive. See the section on the
- handler-commands file.
-
- - e: toggle edit mode. In edit mode the mouse is used for cursor
- positioning. When edit mode is turned off, the mouse functions
- to cut and paste text as usual.
-
- 5. Where the TSnip window opens.
-
- The "on" option lets you select the screen upon which TSnip opens a
- window. The default is the Workbench screen, as if you had entered
- "TSnip on Workbench". There is some flexibility in the way you specify the
- window -- upper and lower case is not significant, and only the first word
- of the title is considered. So if a program has a screen opened called
- "MY PROGRAM'S SCREEN © 1988" you'd only need to say "tsnip on my" to select
- that screen. Also, since many screens open without any title, entering "-null"
- instead of a regular title causes TSnip to use the first untitled screen it
- comes across. Some screens may cause difficulties in determining their
- title, so I included a short program called "Menu" that I wrote way back in
- the dark ages. It'll print out all screen titles, in context, with <NULL>
- for untitled screens.
-
- When the TSnip window is open on a screen other than the Workbench,
- please use extreme caution to avoid having that screen close. Either kill
- TSnip first or move it to a different screen.
-
- 6. What to do with the PIPE: file.
-
- What I personally do is to create a macro within text editors to insert
- the text straight into the editor window, or use the "insert file" option
- from a menu, with filename pipe:tsnip. In DME this can be done by:
-
- map s-f1 `insfile pipe:tsnip'
-
- You may wish to surround the new area with blank lines or do some more
- formatting on it, but just the command to "read the file pipe:tsnip into the
- editor window" should work with _any_ word-processor or editor that supports
- such an operation (almost all). If your editor doesn't or you don't have a
- pipe: device, you can use the keyboard output option to achieve essentially
- the same result.
-
- BTW, this allows me to use "cut and paste" between multiple windows in
- editors that don't have built-in support for it, or between different
- editors.
-
- It's slightly more convenient to use a pipe than a regular file in many
- cases, since when output is to a file you must close the file (by selecting
- a different filename on the control panel, or clearing the filename gadget)
- before you can read it. The pipe file can be opened for reading (multiple
- times if you like) without needing to close it first.
-
-
- 7. Problem windows.
-
- Some windows appear to yield nothing but unrecognized text. If this
- happens you can almost certainly remedy the problem by using the u, d, l
- and r keys while TSnip is running to move the text-outline box to the exact
- position required by that particular window. "Blitz" and "Keep" are two
- programs that open troublesome windows, but they can be TSnipped from OK
- with a bit of experimentation. Once you have found the proper offsets for
- a particular window you can give them as command line arguments to avoid
- any hassles in the future.
-
- Large areas of reversed text, or green-on-purple on some multicolour
- screen, will likely be tough to tsnip from. However you can use the control
- panel to do it like this:
-
- - activate the TSnip window, and open the control panel
- - position the mouse pointer over the window you want to get text from,
- directly above an area in the same colour as the text
- - press 'q' to query the pixel colour below the mouse. It will be
- displayed on the status line of the control panel. This is the colour
- the text is drawn in, and should be between 0 and 31.
- - enter that number in the "textpen" string gadget of the control panel
-
- Now only text in that colour will be recognized, but the background
- will be ignored no matter what colour it is. If you erase the number in
- the textpen gadget TSnip will again recognize text in any colour, but only
- against a background in colour #0 (the standard background).
-
-
- 8. Handler-commands file.
-
- This can be located in your current directory or, preferably, in S:.
- The first line should be the command used by your favourite input handler
- (mine is DMouse) to turn OFF window auto-activation. The second line
- should be the command to turn it back ON. I recommend using an explicit
- path for the commands, otherwise you may get a requester asking you to
- put back the disk from which you ran TSnip.
-
- My handler-commands file looks like this (note that the first command should
- be on the VERY FIRST line of the file):
-
- c:dmouse -A0 -c2
- c:dmouse -A3 -c2
-
- When using this option you must have the regular AmigaDOS Run command in
- your C: directory (as opposed to the ARP Arun). It's a really good idea to
- have addbuffers or FaccII running, or the necessary commands in a ramdisk.
- This is because a command will be run each time the main TSnip window
- is activated or inactivated while the -m option is in effect.
-
- 9. Control panel.
-
- This is a tremendously useful addition. The initial TSnip window is
- only a strip so as not to clutter your screen. If you need some features
- or extra information, you can click on the "Panel" gadget and open a second
- window with gadgets galore. Hitting that gadget again, or the close box
- of the new window, gets rid of the control panel without terminating TSnip.
-
- Your current output destination will be highlighted. You can change it
- by clicking on any of the other output gadgets or via the keyboard
- equivalents. The File gadget holds the name of the file you may have
- specified in the -o command line option. You can change this at any time,
- and the old file will be closed and the new one opened. If you erase the
- filename entirely, output will be printed on the screen (to stdout for you
- C people).
-
- The font currently being recognized is named by the Font gadget. This
- must be an 8x8 font for which you have a .fontdef file in your current
- directory or in S:. These special files are created by the TSNIPGEN program
- that should be included as part of this distribution. If there is no file
- named in the Font gadget TSnip will use an internal bitmap of the topaz 8
- font in Kickstart 1.2. You can change the font at any time, or erase the
- contents of the gadget to go back to the default font.
-
- Most text can be read without concern for its colour. But some text,
- for instance text in the titlebars of most windows, is not plotted against
- a clear background and confuses TSnip. If you want to read some text that
- is like this, use the "q" key to determine what colour the _text_ is in
- that area, by moving the mouse above the text and pressing "q" while the
- TSnip window is active. You will see a message in the control panel telling
- you what colour the text is in. Then type the number which corresponds to the
- text colour into the TextPen gadget.
-
- If you are at all unsure how TSnip is working, look at the bottom line
- of the control panel. As TSnip does its work it prints plain English
- descriptions of the steps it takes here. Helpful information is present
- for almost any action you take.
-
- Other features may be added to the control panel as I think of them or
- as people suggest them.
-
-
- 10. Syntax & Examples.
-
- tsnip <- program will print all messages to the CLI (default)
- tsnip -s <- identical to above
-
- tsnip -o prt: <- redirect output to the printer. You can cut
- multiple pieces of text and have them all
- printed this way.
-
- tsnip -o df0:file <- same deal, except text is all saved in a file
-
- tsnip -p <- text is written to a file called "pipe:tsnip".
- If you don't have a pipe device, you can re-
- assign pipe: to somewhere else, although this
- is less convenient.
-
- tsnip -c <- text is written to the clipboard, unit #0
-
- tsnip -k <- text written to keyboard when next window activated
- tsnip -K <- same as above, but text written as one long line
-
- tsnip 2 1 <- to snip text from a non-standard (ie non-console)
- window, you can specify an (x,y) offset from the
- normal cut position within the window. For
- instance, many versions of VT100 require that you
- give an offset of (0,-1) to work properly. If you
- specify one offset, you must specify both. Note
- that you can also use the keyboard to adjust the
- exact positioning of characters within a window.
-
- tsnip -k 0 -1 <- combination of an output option with x,y offsets
-
- tsnip -f pearl <- use file "pearl.fontdef" or "s:pearl.fontdef" so
- as to recognize text in the pearl 8 font
-
- tsnip -a <- when using output to keyboard, the TSnip window will
- be re-activated once the text is pasted to the
- output window
-
- tsnip -m <- use file "handler-commands" or "s:handler-commands"
- to control a mouse utility program
-
- tsnip -e <- set edit mode, in which the mouse lets you move the
- cursor in vi
-
- tsnip on workbench <- open window on Workbench screen, the default
-
- tsnip -a -K 0 -1 on VT100 <- going whole hog here, output is to keyboard
- without linefeeds, the TSnip window will
- automatically re-activate itself after each
- snip, it will open its window on the custom
- screen of VT100, and the character location
- will be offset the right amount to recognize
- text on that screen
-
- My standard usage is "tsnip -a -k -m -o prt: -vt100 -vi", and I use keyboard
- controls and the control panel to set other options as I need them, such as
- moving to the VT100 screen or recognizing a different font. The option
- -vt100 means that if I need to make use of the vi cursor-positioning
- capabilities, I will be using the VT100 window. The alternatives to this
- option are -z (when using the Manx Z editor), or no specification at all.
-
-
- 11. Added bonus for users of the 'vi' or 'emacs' editors.
-
- I frequently make use of the Unix editor 'vi' when I'm telecommunicating.
- Many other Amiga users do too, and a number also use the vi-clone 'Z' that
- comes with the high-end version of the Aztec compiler. Now vi is a great
- editor for getting things done... except in the area of cursor controls!
- Finding your way around the screen is a very arduous task indeed. The same
- is true of emacs -- I mean, using ^P, ^N, ^F and ^B for cursor movements???
-
- But no more! If you are running TSnip 1.4 you have, in addition to a
- cut and paste utility, a cursor-controller for use with these editors which
- will let you move the cursor around with the mouse; this lets you position
- the cursor or delete a range of lines very easily.
-
- The editor control in TSnip is a seperate mode: while it's turned on you
- won't be able to cut and paste. But you can toggle the 'edit' feature
- by using the e key, or by giving the option -e from the CLI. If you
- use Workbench, you can make edit mode the default by adding the tooltype
- EDITMODE=TRUE to the TSnip icon. At any time when in edit mode, the e key
- will flip you back to regular cut and paste operation.
-
- You position the cursor in edit mode using the right mouse button while
- the small TSnip window is active. First put the pointer above the window
- which contains your terminal program or the Z editor, directly over the
- cursor. Click the RMB once. Now position the pointer over the spot you want
- to move to and click. Voila! There's the cursor.
-
- Deleting lines in vi will also be enhanced using TSnip. If you want to
- delete either forward or backward over a specified range of lines, put the
- cursor on either the first or last line of the range. Enter "d" _in the
- editor window_ (not the TSnip window), then go through the procedure for
- cursor positioning to move the cursor to the other end of the range. All
- lines including the ones delimiting the range will be deleted. If you want
- to yank a range of lines, again you can do it the same way by entering the
- initial "y" command in the editor window then positioning the cursor.
-
- I'm not familiar enough with emacs to say whether you can do similar
- tricks there too. But I expect inventive minds will find some :-).
-
- There are some things you must know in order for the process to go
- smoothly. First, TSnip needs to know where you're running the editor since
- you might be doing it local or in a terminal window. There are 4 command
- line options defined that TSnip can use to tell exactly how it should act
- in edit mode. These are:
-
- - from CLI: inform TSnip about special editor windows with -z or -vt100
- tell TSnip what editor you will be using with -vi or -emacs
-
- - from Workbench: a tooltype EDITWINDOW=z or vt100
- a tooltype EDITOR=vi or emacs
-
- It's especially important if you're using Z, due to a bug in Z's
- cursor positioning routine (it thinks column numbers start at 0 when using
- the | position command). If you omit these specifications, cursor movement
- will still work but you may need to use u, d, l, and r keys while in edit
- mode to position the 8 x 8 hitbox TSnip uses to tell where a row or
- column starts. These offsets are seperate from those used when snipping
- text.
-
- NOTE: There is no reliable way to deal with lines longer than 80 columns
- which wrap on the screen. If you move the cursor across one of
- these lines the cursor will end up one row off from your intended
- destination (still much better than the clumsy manual method of
- positioning).
-
- If anyone wishes to add similar routines for other editors like
- EDT, etc. please do so and send them to me. I will incorporate them
- into future versions of TSnip.
-
-
- 12. Credits.
-
- Window-locating routine by
- Davide P. Cervone
- Bug fix for setting/restoring drawmodes suggested by
- Leo Schwab
- Idea for improving efficiency via ModifyIDCMP from
- Bryce Nesbitt
- Several who responded with the idea of using a union to achieve about
- a 200% speed increase in text recognition
- Clipboard code from an example by
- Andy Finkel and Bob "Kodiak" Burns
- Code to send events to the input device adapted from "Ping" by
- Chris Saulit
- A timely reminder when I had quite forgotten about Snip from
- Phil Kasten
- SetFont, the program which makes the font options worthwhile, by
- Dave Haynie
- Greatly helpful feedback and suggestions, plus uploading to PLink, from
- Cas Borkowski (PLink SRU885)
- Workbench support code taken from CMD by
- Carolyn Scheppner
-
-