=========================================================================== =========================================================================== ============================ ============================ ============================ ============================ ============================ PARSE-O-MATIC ============================ ============================ ============================ ============================ ============================ =========================================================================== =========================================================================== +-------------------------------------------------------------------------+ | | | HERE ARE A FEW OF THE THINGS PARSE-O-MATIC CAN DO FOR YOU: | | | | Importing Exporting Automated Editing | | Text Extraction Data Conversion Table Lookup | | Retabulation Info Weeding Selective Copying | | Binary-File to Text Report Reformatting Wide-Text Folding | | Auto-Batch Creation Comm-log Trimming Tab Replacement | | Character Filtering Column Switching DBF Interpretation | | De-uppercasing Name Properization And much more! | | | | "Parse-O-Matic is a wonderful time saver .... Each report that | | I can convert from our ... accounting system saves our company | | about 500 man hours per year" -- R. Brooker (a happy POM user) | | | +-------------------------------------------------------------------------+ Parse-O-Matic is Copyright (C) 1986, 1995 by: Pinnacle Software, CP 386 Mount Royal, Quebec, Canada H3P 3C6 U.S. Office: Box 714 Airport Road, Swanton, Vermont 05488 USA Support Line: (514) 345-9578 Free Files BBS: (514) 345-8654 Internet email: pinnacl@cam.org World Wide Web: http://www.cam.org/~pinnacl CompuServe: 70154,1577 +-------------------------------------------------------------------------+ | | | FILE FORMATS CURRENTLY SUPPORTED BY PARSE-O-MATIC: | | | | Input: Text (almost any format), Binary, Fixed-Length, DBF | | Output: Text (flat, comma-delimited, paginated), Binary, Fixed-Length | | | +-------------------------------------------------------------------------+ =========================================================================== AN OVERVIEW OF THIS MANUAL =========================================================================== Introduction . . . . . . . . What is Parse-O-Matic? Why you need Parse-O-Matic -- an example Parse-O-Matic to the rescue! How it works Fundamentals . . . . . . . . The Parse-O-Matic command The POM file Padding for clarity A simple example Quick Reference . . . . . . Related commands Command formats Input Parsing Commands . . . Set, If, Parse, Peel Flow Control Commands . . . Begin, Else, End, Done, Nextfile Output Commands . . . . . . Out, Outend, Outhdg, Pagelen Filter Commands . . . . . . Minlen, Ignore, Accept, Readnext Variable Modifiers . . . . . Trim, Pad, Change, Proper, Insert, Append Input Preprocessors . . . . Split, Chop Lookup Commands . . . . . . Lookup, Lookfile, Lookcols, Lookspec Miscellaneous Commands . . . Trace, Setlen, Sound Terms and Techniques . . . . Values Delimiters Illegal characters Comparators Incrementing Line counters Tracing Logging Quiet mode DBF Files POM and wildcards Operational Planning . . . . Unattended operation Converting comma-delimited files Examples Licensing . . . . . . . . . Trial license Registered copy Site and Multi-copy licenses Distribution license Retail license =========================================================================== INTRODUCTION =========================================================================== ---------------------- What is Parse-O-Matic? ---------------------- Parse-O-Matic is a programmable file-parser. Simple enough for even a non- programmer to master, it can help out in countless ways. Here are some of the things Parse-O-Matic can do: Importing, Exporting, Automated Editing, Text Extraction, Data Conversion, Table Lookup, Retabulation, Info Weeding, Selective Copying, Binary-File to Text, Tab Replacement, Reformatting, Wide-Text Folding, Auto-Batch Creation, Character Filtering, Column Switching, DBF Interpretation, Report Generation, and more! If you have a file you want to edit, manipulate, or change around, you may find that Parse-O-Matic is just the tool you need. Parse-O-Matic is not, however, an "automatic file converter". It will not, for example, convert WordPerfect files to MS-Word format, or convert Lotus 1-2-3 Spreadsheets DIRECTLY to Excel files (although you CAN use Parse-O-Matic as an intermediary, by having it read reports from one program and convert them to comma-delimited files which can be imported by the other program.) ---------------------------------------- Why You Need Parse-O-Matic -- An Example ---------------------------------------- There are plenty of programs out there that have valuable data locked away inside them. How do you get that data OUT of one program and into another one? Some programs provide a feature which "exports" a file into some kind of generic format. Perhaps the most popular of these formats is known as a "comma-delimited file", which is a text file in which each data field is separated by a comma. Character strings -- which might themselves contain commas -- are surrounded by double quotes. So a few lines from a comma-delimited file might look something like this (an export from a hypothetical database of people who owe your company money): +-------------------------------------------------------------------------+ | "JONES","FRED","1234 GREEN AVENUE", "KANSAS CITY", "MO",293.64 | | "SMITH","JOHN","2343 OAK STREET","NEW YORK","NY",22.50 | | "WILLIAMS","JOSEPH","23 GARDEN CRESCENT","TORONTO","ON",16.99 | +-------------------------------------------------------------------------+ Unfortunately, not all programs export or import data in this format. Even more frustrating is a program that exports data in a format that is ALMOST what you need! If that's the case, you might decide to spend a few hours in a text editor, modifying the export file so that the other program can understand it. Or you might write a program to do the editing for you. Both solutions are time-consuming. An even more challenging problem arises when a program which has no export capability does have the ability to "print" reports to a file. You can write a program to read these files and convert them to something you can use, but this can be a LOT of work! ---------------------------- Parse-O-Matic to the Rescue! ---------------------------- Parse-O-Matic is a utility that reads text, fixed-record-length and DBF ("DBase") files, interprets the data, and outputs the result to a text, fixed-length or binary file. It can help you "boil down" reports into their essential data. You can also use it to convert NEARLY compatible import files, or generate printable reports. ------------ How It Works ------------ You need three things: 1) The Parse-O-Matic program 2) A Parse-O-Matic "POM" file (to tell Parse-O-Matic what to do) 3) The input file The input file is usually a report from another program, a fixed record length data file, or a DBF ("DBase") file. We've provided several examples of typical input files. For example, the file XMPDAT02.TXT comes from the AccPac accounting software. AccPac is a great program, but its export capabilities leave something to be desired. Parse-O-Matic can help! To see detailed demonstrations of how these files can be parsed, enter START at the DOS prompt, then select TUTORIAL. =========================================================================== FUNDAMENTALS =========================================================================== This documentation assumes that you are an experienced computer user. If you have trouble, you might ask a programmer to help you -- POM file creation is a little like programming! ------------------------- The Parse-O-Matic Command ------------------------- The basic format of the Parse-O-Matic command line is: POM pom-file input-file output-file Here is an example, as you would type it at the DOS command line: POM POMFILE.POM REPORT.TXT OUTPUT.TXT For a more formal description of the command line, start up POM by typing this command at the DOS prompt: POM ------------ The POM File ------------ The POM file is a text file with a .POM extension. The following conventions are used when interpreting the POM file: - Null lines and lines starting with a semi-colon (comments) are ignored. - A POM file may contain up to 500 lines of specifications. Comment lines do not count in this total. A POM file contains no "loops" (to use the programming term). Each line of the input file is processed by the entire POM file. If you'd like this expressed in terms of programming languages, here's what POM does: +-------------------------------------------------------------------------+ | START: If there's nothing left in the input file, go to QUIT. | | Read a line from the input file | | Do everything in the POM file | | Go to START | | QUIT: Tell the user you're finished! | +-------------------------------------------------------------------------+ ------------------- Padding for Clarity ------------------- Spaces and tabs between the words and variables in a POM file line are generally ignored (except in the case of the "output picture" of the OUT and OUTEND commands). You can use spaces to make your POM files easier to read. Additionally, in any line in the POM file, the following terms are ignored: THEN ELSE Finally, the equals ("=") character is ignored if it is found in a place where no comparison is taking place. This will be demonstrated below. You can use these techniques to make your POM files easier to read. For example, the IF command can be written in several ways: Very terse: IF PRICE = "0.00" BONUS "0.00" "1.00" Padded with spaces: IF PRICE = "0.00" BONUS "0.00" "1.00" Fully padded: IF PRICE = "0.00" THEN BONUS = "0.00" ELSE "1.00" In the last example, the first equals sign ("=") is a "comparator". (For details about comparators, see the section entitled "Comparators".) The second equals sign is not really required, but it does make the line easier to understand. ---------------- A Simple Example ---------------- Let's say you have a text file called NAMES.TXT that looks like this: WILLIAMS JACK SMITH JOHNNY JOHNSON MARY : : Column 1 Column 12 Now let's say you want to switch the columns, so that the first name appears first. Your first step is to create a file using a text editor. The file would look like this: SET last = $FLINE[ 1 10] SET first = $FLINE[12 17] PAD first "R" " " "10" OUTEND |{first} {last} The first two lines will tell Parse-O-Matic to extract text from each input line. For the first line of the input file, the variable named 'last' will be given the value "WILLIAMS ". You will notice there are two spaces at the end. That is because we take every character from position 1 to position 10 -- which in this case includes two spaces. The PAD line adds enough spaces on the right side of the variable named 'first' to make sure that it is 10 characters long. The OUTEND command sends the two variables to the output file. Save the file with the name TEST.POM and exit your text editor. At the DOS prompt, enter this command: POM TEST.POM NAMES.TXT OUTPUT.TXT This will run the POM file (TEST.POM) on every line of the input file (NAMES.TXT) and place the output in the file OUTPUT.TXT, which will then look like this: JACK WILLIAMS JOHNNY SMITH MARY JOHNSON : : Column 1 Column 12 Of course, for such a simple task, it would be easier to switch the columns yourself, using a text editor. But when you are dealing with large amounts of data, and want to guard against typing errors, Parse-O-Matic can save you a lot of time, effort and risk. It also lets you automate editing operations that you perform frequently. =========================================================================== QUICK REFERENCE =========================================================================== ---------------- Related Commands ---------------- For ease of learning, the "Command Words" section explains each command in the following order: COMMANDS WHICH WILL... LIST OF COMMANDS ---------------------------------- ------------------------------------ Break up an input line into fields SET IF PARSE PEEL Control processing flow BEGIN ELSE END DONE NEXTFILE Generate or control output OUT OUTEND OUTHDG PAGELEN Accept or reject input MINLEN IGNORE ACCEPT READNEXT Alter variables TRIM PAD CHANGE PROPER INSERT APPEND Preprocess input SPLIT CHOP Look up data in another file LOOKUP LOOKFILE LOOKCOLS LOOKSPEC Perform miscellaneous functions TRACE SETLEN SOUND --------------- Command Formats --------------- Here is a quick-reference table of all the commands. The following conven- tions are used in the table: "var" means a variable that is being set. "c" means a comparator (if omitted, defaults to "equals") "value" means a variable whose value is being read. Square brackets [like this] indicate optional items. ------------------------------------------- ------------------------------ COMMAND FORMATS EXAMPLE =========================================== ============================== ACCEPT value c value ACCEPT $FLINE[1 3] = "YES" APPEND var value value [value [value]] APPEND name first last BEGIN value c value BEGIN linecntr < "3" CHANGE var value value CHANGE date "/" "-" CHOP from to [,from to] [...] CHOP 1 250, 251 300 DONE [value c value] DONE $FLINE = "End Data" ELSE ELSE END END IF value c value var value [value] IF x = "Y" THEN z = "N" IGNORE value c value IGNORE price = "0.00" INSERT var spec value INSERT price "L" "$" LOOKCOLS value value value value LOOKCOLS "1" "3" "8" "255" LOOKFILE value LOOKFILE "C:\TABLES\DATA.TBL" LOOKSPEC value value value LOOKSPEC "Y" "N" "N" LOOKUP var value LOOKUP phonenum "FRED JONES" MINLEN value MINLEN "15" NEXTFILE [value c value] NEXTFILE $FLINE = "End File" OUT [value c value] |output-picture OUT z = "X" |{price} OUTEND [value c value] |output-picture OUTEND z = "X" |{$FLINE} OUTHDG value OUTHDG "LIST OF EMPLOYEES" PAD var spec character len PAD sernum "L" "0" "10" PAGELEN value [value] PAGELEN "66" "N" PARSE var value from to [control] PARSE x $FLINE "2*(" "3*)" PEEL var var from to [control] PEEL x $FLINE "2*(" "3*)" PROPER var [methods [exceptions-file]] PROPER custname "I" "XY.PEF" READNEXT [value c value] READNEXT $FLINE[1 5] = "NOTE:" SET var value SET name $FLINE[20 26] SETLEN var value SETLEN length custname SOUND value SOUND "BUZZ" SPLIT from to [,from to] [...] SPLIT 1 250, 251 300 TRACE var TRACE price TRIM var spec character TRIM price "R" "$" ------------------------------------------- ------------------------------ The commands are explained in more detail in the "Command Words" section. A summary of the commands and default settings appear in the comments at the beginning of the file EXAMPL04.POM. You can copy these comments into your own POM file as a convenient quick reference. =========================================================================== INPUT PARSING COMMANDS =========================================================================== COMMAND DESCRIPTION ------- ----------- SET Assigns a value to a variable IF Conditionally assigns a value to a variable PARSE Obtains a variable found between delimiters in free-form data PEEL Works like PARSE, but removes the "found" text from the data --------------- The SET Command --------------- FORMAT: SET var1 value1 SET assigns a value to a variable. The usual reason to do this is to set a variable from the input line (represented by the variable $FLINE) prior to cleaning it up with TRIM. For example, if the input line looked like this: JOHN SMITH 555-1234 322 Westchester Lane Architect | | | | | Column 1 Col 12 Col 22 Col 33 Col 57 then we could extract the last name from the input line with these two POM commands: SET NAME = $FLINE[12 21] (Sets the variable from the input line) TRIM NAME "R" " " (Trims any spaces on the right side) SET would first set the variable NAME to this value: "SMITH " After the TRIM, the variable NAME would have the value: "SMITH" You will also use SET if you plan to include a substring of $FLINE in the output, since the OUT and OUTEND commands do not recognize substrings after the "|" marker, only complete variables. -------------- The IF Command -------------- FORMAT: IF value1 [comparator] value2 var1 value3 [value4] NOTE: For an explanation of comparators, see the section "Comparators". In the following explanation, we will demonstrate the command using only the "equals" ("=") comparator. If value1 equals value2, var1 is set to value3. Otherwise, it is set to value4 (if value4 is missing, nothing is done, and var1 is not changed). Here's an example of the IF command... SET EARNING = $FLINE[20 23] IF EARNING = "0.00" THEN BONUS = "0.00" ELSE "1.00" This obtains the value between columns 20 and 26, then checks if it equals "0.00". If it does, the variable BONUS is set to 0.00. If not, BONUS is set to "1.00". The "THEN" and "ELSE" are "padding" and can be omitted. --------------------------- The PARSE and PEEL Commands --------------------------- FORMAT: PARSE var1 value1 from to [control] PEEL var1 var2 from to [control] NOTE: PARSE is a very powerful command. As a result, the explanation is somewhat complex. If you are reading this manual for the first time, you may wish to skip this part for now, and come back to it later. The PARSE command is used for extracting information from an input line that does not have its data in precise columns. Consider the following input file: Mouse Gazelle Mouse Elephant Dog Giraffe Elk Mongoose Monkey Snake Caribou Trout | | | | Column 1 Col 11 Col 21 Col 31 Extracting data that is arranged in tidy columns is simple -- all you need is the SET command. However, you will need a more powerful command if the data is in "free-form", like this: Mouse,Gazelle,Mouse,Elephant Dog,Giraffe,Elk,Mongoose Monkey,Snake,Caribou,Trout The PARSE command lets you extract the "Nth" item. For example, to extract the third item in each line in the free-form example above, you could use this command: PARSE xyz $FLINE "2*," "3*," This means "set the variable xyz by looking in $FLINE (the line just read from the input file) and taking everything between the second comma and the third comma". For the three lines in the sample input file, the variable xyz is set to Mouse, then Elk, then Caribou. In the "From" specification (i.e. the "2*," part of the command): 2 means "the second occurance" * is a delimiter to mark the end of the occurance number , is the text you are looking for Both the "From" and "To" specifications use this format. Incidentally, the text you are looking for can be more than a single character -- it can be up to 80 characters long. Let's say the input file looks like this: Mouse:::Gazelle:::Mouse:::Elephant Dog:::Giraffe:::Elk:::Mongoose Monkey:::Snake:::Caribou:::Trout You can extract the third item in each line with this command: PARSE xyz $FLINE "2*:::" "3*:::" ___ ______ _ ___ _ ___ | | | | | | Variable to set | | | | | The value to parse | | | "To" text being sought "From" occurance number | "To" occurance number "From" text being sought This command sets the variable xyz to Mouse, then Elk, then Caribou. The PARSE command is particularly useful for extracting information from comma-delimited files. Here is an example of a comma-delimited file: "Mouse","Gazelle","Mouse","Elephant" "Dog","Giraffe","Elk","Mongoose" "Monkey","Snake","Caribou","Trout" You can extract all the fields with this series of commands (note the use of doubled-up quotes to represent a single quotation mark -- see the section "Delimiters" for details): PARSE field1 $FLINE "1*""" "2*""" PARSE field2 $FLINE "3*""" "4*""" PARSE field3 $FLINE "5*""" "6*""" PARSE field4 $FLINE "7*""" "8*""" For the first line of the sample input file, field1 is set to Mouse, field2 is set to Gazelle, and so on. The occurance number is not always needed. Here are some variations of the "From" specification that you might find helpful: "" = Start from the first character in the value being parsed "XYZ" = Start from the first "XYZ" found in the value being parsed Similar variations can be used with the "To" specification: "" = End with the last character in the value being parsed "XYZ" = End with the first "XYZ" found in the value being parsed The occurance number must be between 1 and 255. The following lines are not valid PARSE commands: PARSE xyz $FLINE "0*," "1*," (uses 0) PARSE xyz $FLINE "1*," "256*," (uses 256) The occurance number is always be followed by a "*" so you can search for a number. Consider the following example (the meaning of which would be unclear without the "*" delimiter): PARSE xyz "XXX2YYY2ZZZ2" "1*2" "2*2" This sets xyz to the text occuring between the first "2" and the second "2". In other words, xyz is set to "YYY". If PARSE does not find the search text, or if the "To" text occurs before the "From" text, the variable will be set to a null (""). Here are several examples: PARSE abc "ABCDEFGHIJ" "1*K" "1*J" (There is no "K") PARSE abc "ABCDEFGHIJ" "1*A" "1*X" (There is no "X") PARSE abc "ABCDEFGHIJ" "1*J" "1*A" ("J" comes after "A") The PARSE command has an optional "control" parameter, which tells PARSE whether to include or exclude the text that was found. By default (as shown in all of the preceding examples), the found text is excluded. However, if you want to include the found text, you can add "I" at the end of the PARSE command, as in this example: PARSE xyz "aXcaYcaZc" "2*a" "2*c" "I" This sets the variable xyz to "aYc". You can also set the control specification to "X" (meaning "exclude"), although since this is the default setting for PARSE, it really isn't necessary. Here is an example: PARSE xyz "a1ca2ca3c" "2*a" "2*c" "X" This sets the variable xyz to "2". There is one exception to the behaviour of the control setting. If you use the null ("") specification for "From" or "To", the "found" value (the first character for "From", or the last character for "To") will always be included. Here is an example: PARSE xyz "ABCABCABC" "" "2*C" This sets the variable xyz to "ABCAB". The "From" value (i.e. the first character) is not excluded. However, when PARSE finds the "To" value (i.e. the second occurance of the letter C) it is excluded. If you want to include the second "C", you should write the command this way: PARSE xyz "ABCABCABC" "" "2*C" "I" The following two commands accomplish the same thing: PARSE xyz "ABCD" "" "" SET xyz "ABCD" They are equivalent because the PARSE command means "Set the variable xyz with everything between (and including) the first and last character". The reason that PARSE treats the null ("") specification differently may not be immediately obvious, since the examples given here are very simple, and not representative of "real world" applications. However, in day-to-day usage, you will frequently find it helpful to be able to specify a command that says, "Give me everything from the beginning of the line to just before such-and-such". Here is a command that means "Give me everything from just after the dollar sign, to the end of the line": PARSE xyz "I'd like to have $250.00" "1*$" "" This sets xyz to "250.00". If you want to include the dollar sign, write the command this way: PARSE xyz "I'd like to have $250.00" "1*$" "" "I" For more examples of the PARSE command, see the demonstrations provided with Parse-O-Matic (type START at the DOS prompt, then select TUTORIAL). The PEEL command works just like PARSE, but after setting var1, it REMOVES the parsed value (including the delimiters) from var2. When you are breaking up a complex line into fields, this can simplify matters considerably, because the line gradually becomes less complex. Here is a simple example. Let's say you have an input file containing a single line: AA/BB/CC/DD If you run this POM file against the input file: PEEL x $FLINE "" "/" <--- Strips out the AA, removes the / OUTEND |{x} PEEL x $FLINE "" "/" <--- Strips out the BB, removes the / OUTEND |{x} PEEL x $FLINE "" "/" <--- Strips out the CC, removes the / OUTEND |{x} OUTEND |{$FLINE} then the output file will look like this: AA BB CC DD What is happening is that $FLINE is gradually being stripped of the text that is being found. After the first PEEL, $FLINE contains "BB/CC/DD", and so on. After the final PEEL, $FLINE only contains "DD". The "I" and "X" control parameters behave the same way as they do in the PARSE command. Take note, however, that the starting and ending characters are always removed, along with the "found" text, regardless of the control parameter. The control parameter only affects the first variable (x in the example above), not the second ($FLINE in the example). =========================================================================== FLOW CONTROL COMMANDS =========================================================================== COMMAND DESCRIPTION ------- ----------- BEGIN Defines the conditions for processing the code block ELSE Defines the start of code to be processed if the BEGIN fails END Marks the end of a BEGIN/END or BEGIN/ELSE/END code block DONE Reads the next input line and starts at the top of the POM file NEXTFILE Skips the current input file and proceeds to the next one -------------------------------- The BEGIN, ELSE and END Commands -------------------------------- The format for the BEGIN and END commands is as follows: BEGIN value1 [comparator] value2 : Dependant code : END NOTE: For an explanation of comparators, see the section "Comparators". In the following explanation, we will demonstrate the command using only the "equals" ("=") comparator. If value1 equals value2, then the dependant code (the POM lines between the BEGIN and the END) are executed. If value1 does not equal value2, then the dependant code is skipped. It is traditional in programming to indent code that appears in blocks such as Parse-O-Matic's BEGIN/END technique. This makes the logic of the program easier to understand. For example: BEGIN datatype = "Employee" SET phone = $FLINE[ 1 10] SET address = $FLINE[12 31] END BEGIN/END blocks can be nested. That is to say, you can have BEGIN/END blocks inside other BEGIN/END blocks. Here is an example, with arrows to indicate the levels of each BEGIN/END block... BEGIN datatype = "Employee" <--------------------- SET phone = $FLINE[ 1 10] | SET address = $FLINE[12 31] | SET areacode = phone[1 3] | First BEGIN areacode = "514" <------- Second | Level SET local = "Y" | Level | Block SET tax = "Y" <------- Block | END | END <--------------------- In this case, the "inner" block (starting with BEGIN areacode = "514") is reached only if the "outer" block (BEGIN datatype = "Employee") is true. If the outer block is false, the inner block is ignored. A nested BEGIN/END block must always be completely inside the outer block. Study the following (incorrect) example: BEGIN datatype = "Employee" <---- SET phone = $FLINE[ 1 10] | First SET areacode = phone[1 3] | Level BEGIN areacode = "514" <--- | Block? SET local = "Y" | | END | <---- SET tax = "Y" | END <--- Second Level Block? Parse-O-Matic does not pay attention to the indenting -- it is only a tradition we use to make the file easier to read. The code will be understood this way: BEGIN datatype = "Employee" <--------------------- SET phone = $FLINE[ 1 10] | First SET areacode = phone[1 3] | Level BEGIN areacode = "514" <--- Second | Block SET local = "Y" | Level | END <--- Block | SET tax = "Y" | END <--------------------- You can nest BEGIN/END blocks up to 25 deep -- although it is unlikely you will ever need that much nesting. Here is an example of code that uses nesting up to three deep: BEGIN datatype = "Dog" <---------------------------------- SET breed = $FLINE[1 10] | First BEGIN breed = "Collie" <----------------------- | Level SET noise = "Woof" | Second | Block BEGIN name = "Spot" <------ Third | Level | SET attitude = "Friendly" | Level | Block | END <------ Block | | END <----------------------- | BEGIN breed = "Other" <----------------------- Another | SET noise = "Arf" | Second | SET attitude = "Unknown" | Level | END <----------------------- Block | END <---------------------------------- Once again, the indentation is for clarity only and does not affect the way the POM file runs. However, you will find that it makes your POM file much easier to understand. The ELSE command tells Parse-O-Matic to execute the following block of code (up until the END command) if the corresponding BEGIN comparison is NOT true. NOTE: The ELSE command should not be confused with the ELSE used to pad the IF statement (e.g. IF $FLINE[1] = "3" THEN x = "Y" ELSE "N"). In the IF command, the ELSE is included to make the statement easier to understand, and can be omitted (e.g. IF $FLINE[1] "3" x "Y" "N"). The format of a BEGIN/ELSE/END block is as follows: BEGIN value1 [comparator] value2 : Code that is run if the comparison is true : ELSE : Code that is run if the comparison is false : END Here is an example: BEGIN $FLINE[1 10] = "JOHN SMITH" SET x = "This is John" ELSE SET x = "This is not John" END If you are using several levels of nesting, you should indent your code to show the relationship of the various BEGIN, ELSE and END statements. Here is an example: BEGIN datatype = "Dog" <---------------------------------- SET breed = $FLINE[1 10] | First BEGIN breed = "Collie" <----------------------- | Level SET noise = "Woof" | Second | Block BEGIN name = "Spot" <------ Third | Level | SET attitude = "Friendly" | Level | Block | END <------ Block | | ELSE | | SET noise = "Arf" | | SET attitude = "Unknown" | | END <----------------------- | END <---------------------------------- The ELSE is at "Level 2". This is because there are three BEGINs ahead of it, but only one END (3 - 1 = 2). Here are two helpful rule to remember: - A POM file will always contain the same number of BEGINs and ENDs - The number of ELSEs can never exceed the number of BEGINs ---------------- The DONE Command ---------------- FORMAT: DONE [value comparator value] NOTE: For an explanation of comparators, see the section "Comparators". In the following explanation, we will demonstrate the command using only the "equals" ("=") comparator. The DONE command will discontinue processing the POM file and proceed to the next input line, whereupon the POM file will restart at the top. The DONE command is most useful when you have a long series of BEGIN/END blocks which make a related comparison. For example: SET salesrep = $FLINE[11 50] SET region = $FLINE[ 1 2] BEGIN region = "US" OUTEND |Sales representative for U.S.A.: {salesrep} DONE END BEGIN region = "CN" OUTEND |Sales representative for Canada: {salesrep} DONE END BEGIN region = "EU" OUTEND |Sales representative for Europe: {salesrep} DONE END : etc. As you can see, if one of the BEGIN comparisons is true, all of the following ones will inevitably be false. Rather than processing all the others, you can use the DONE command to bail out and get ready for the next input line. The DONE command provides two benefits: - It can speed up processing slightly - It makes full traces easier to understand For an explanation of traces, see the section entitled "Tracing". Unless you use a comparison (explained later), the DONE command is useful only inside BEGIN/ELSE/END blocks. If you write a POM file like this: SET custnum = $FLINE[ 1 10] SET custname = $FLINE[11 50] DONE OUTEND |{custname} {custnum} the OUTEND statement will NEVER be reached. Here is how you specify a comparison for the DONE command: DONE $FLINE = "End of Data" This discontinues the POM file, and proceeds to the next input line, if the current input line ($FLINE) is "End of Data". -------------------- The NEXTFILE Command -------------------- FORMAT: NEXTFILE [value comparator value] NOTE: For an explanation of comparators, see the section "Comparators". In the following explanation, we will demonstrate the command using only the "equals" ("=") comparator. The NEXTFILE command is useful when you process multiple input files (see "POM and Wildcards"). It discontinues processing the current input file and proceeds to the next one. The POM file restarts from the top. Here is an example, which we will call TEST.POM: BEGIN $FLINE = "End of Data" OUTEND |{numlines} lines of data printed SET numlines = "" NEXTFILE END SET numlines = numlines+ OUTEND |{$FLINE} Let's say you have three text files: DATA1.XYZ, DATA2.XYZ and DATA3.XYZ. The last line of each file says "End of Data". You could copy all three files to the file OUTPUT.TXT with this command: POM TEST.POM DATA?.XYZ OUTPUT.TXT This would copy the data from each file, but when it gets to the line reading "End of Data", it records the number of lines of data that were printed. Any lines after the "End of Data" line are skipped, because of the NEXTFILE command. The NEXTFILE command can specify a comparison. Here is an example: NEXTFILE $FLINE = "End of Data" OUTEND |{$FLINE} Assuming the same input files (DATA1.XYZ etc.), and using the same POM command as last time, this POM file would simply copy up to (but not including" the line that reads "End of Data" in each input file. =========================================================================== OUTPUT COMMANDS =========================================================================== COMMAND DESCRIPTION ------- ----------- OUT Sends text and variables to the output file OUTEND Like OUT but adds a new line at the end (Carriage Return/Linefeed) OUTHDG Sets up title lines to appear at the top of a report or each page PAGELEN Sets the page length for a report --------------------------- The OUT and OUTEND Commands --------------------------- FORMAT: OUT[END] [value1 [comparator] value2] |output-picture NOTE: For an explanation of comparators, see the section "Comparators". In the following explanation, we will demonstrate the command using only the "equals" ("=") comparator. The OUT command generates output without an end-of-line (i.e. carriage return and linefeed characters). The OUTEND command generates output and also adds an end-of-line. When value1 equals value2, a line is sent to the output file, according to the output picture. Within the output picture, all text is taken literally (i.e. " is taken to mean literally that -- a quotation mark character). The only exception to this is variable names, which are identified by the { and } characters. For example, a POM file that contained the following single line: OUTEND "X" = "X" |{$FLINE} would simply output every line from the input file (not very useful!). The "X" = "X" part of the command is the comparison which controls when output occurs. In the example above, both values being compared are the same, so output will always occur. You can not use substrings after the "|" marker. Thus, the following line is NOT legal: OUTEND $FLINE[1 3] = "IBM" |{$FLINE[1 15]} The correct way to code this is as follows: SET CODE = $FLINE[1 15] OUTEND $FLINE[1 3] = "IBM" |{CODE} This outputs the first 15 characters of any line that contains the letters "IBM" in the first three positions. ------------------------------- The OUTHDG and PAGELEN Commands ------------------------------- FORMAT: OUTHDG value1 FORMAT: PAGELEN value1 [value2] OUTHDG is used to place text headers in your output. For example, if you were parsing data to create an employee report, you might use OUTHDG like this: SET EMPNUM = $FLINE[ 1 5] SET NAME = $FLINE[10 28] SET PHONE = $FLINE[30 45] OUTHDG "EMPL# NAME PHONE NUMBER" OUTHDG "----- ------------------- ------------" OUTEND |{EMPNUM} {NAME} {PHONE} The value following the OUTHDG command is sent to the output file only once. That is to say, after an OUTHDG sends a value to the output file, subsequent encounters with that OUTHDG command are ignored -- unless the PAGELEN command is used. The PAGELEN command specifies the length of the output page. Lines from both OUTHDG and OUTEND are counted. The default value for page length is zero, which means that the output is a single page of infinite length. As such, OUTHDG headings appear only the first time they are encountered. If you specify a page length greater than zero, OUTHDG headings become re-enabled once the specified number of output lines have been generated. A typical value is as follows: PAGELEN "55" This is an ideal page length for most laser printers. Dot matrix printers typically use a page length of 66. Parse-O-Matic inserts a "form feed" (ASCII 12) character between pages. You can turn this off, however, by specifying the page length this way: PAGELEN "66" "N" The "N" specification means, "No, don't use form feeds". Another acceptable value is "Y", meaning "Yes, use form feeds", but since this is the default, you do not have to specify it. =========================================================================== FILTER COMMANDS =========================================================================== COMMAND DESCRIPTION ------- ----------- MINLEN Sets the minimum length required for an input line to be processed IGNORE Ignores an input line that meets the specified condition ACCEPT Accepts an input line that meets the specified condition READNEXT Moves to next input line but retains your place in the POM file ------------------ The MINLEN Command ------------------ FORMAT: MINLEN value1 MINLEN specifies the minimum length a line must be to be considered for parsing. If you omit the MINLEN command, the minimum length is assumed to be 1. That is to say, all lines 1 character or longer will be processed and shorter lines (null lines in other words) will be ignored. MINLEN is useful for ignoring brief information lines that clutter up a report that you are parsing. For example, in the sample file EXAMPL02.POM, the MINLEN command is set to 85 to ensure that all lines shorter than 85 characters long will be ignored. This simplifies the coding considerably. The longest allowable input line is 255 characters, unless you use the SPLIT or CHOP command (described later). ------------------ The IGNORE Command ------------------ FORMAT: IGNORE value1 [comparator] value2 NOTE: For an explanation of comparators, see the section "Comparators". In the following explanation, we will demonstrate the command using only the "equals" ("=") comparator. When value1 contains value2, the input line is ignored and all further processing on the input line stops. The usual format of this command is as in this example: IGNORE $FLINE[3 9] = "Date" This skips any input line that contains the word "Date" between columns 3 and 9 ($FLINE is the line just read from the input file). ------------------ The ACCEPT Command ------------------ FORMAT: ACCEPT value1 [comparator] value2 NOTE: For an explanation of comparators, see the section "Comparators". In the following explanation, we will demonstrate the command using only the "equals" ("=") comparator. The ACCEPT command accepts the input line if value1 contains value2. For example, if the entire POM file read as follows: ACCEPT $FLINE[15 17] = "YES" OUTEND "X" = "X" |{$FLINE} then any input line that contains "YES" starting in column 15 is sent to the output file. All other lines are ignored. CLUSTERED ACCEPTS: Sometimes you have to check more than one value to see if the input line is valid. You do this by using "clustered ACCEPTs", which are several ACCEPT commands in a row. Briefly stated, if you have several ACCEPTs in a row ("clustered"), they are all processed to determine if the input line is acceptable or not. If even one ACCEPT matches up, the line is accepted. To express this in more detail... When value1 contains value2, the line is accepted, and processing of the POM file continues for that input line, even if the immediately following ACCEPTs do NOT produce a match. After all, we've already got a match! If value1 does NOT contain value2, Parse-O-Matic looks at the next commmand in the POM file. If it is not another ACCEPT, the input line is ignored. If it is another ACCEPT, maybe it will product a match -- so Parse-O-Matic moves to that command. The following POM file uses clustered ACCEPTs to accept any line that contains the name "FRED" or "MARY" between columns 5 and 8, or contains the word "MEMBER" between columns 20 and 25. SET NAME = $FLINE[5 8] (Set the variable) ACCEPT NAME = "FRED" (Look for FRED) ACCEPT NAME = "MARY" (Look for MARY) ACCEPT $FLINE[20 25] = "MEMBER" (Look for MEMBER) OUTEND "X" = "X" |{$FLINE} (Output the line if we get this far) The following example will NOT work, however: ACCEPT $FLINE[20 25] = "MEMBER" SET NAME = $FLINE[5 8] ACCEPT NAME = "FRED" ACCEPT NAME = "MARY" OUTEND "X" = "X" |{$FLINE} It will not work because the ACCEPTs are not clustered; if the first ACCEPT fails, the input line is rejected as soon as the SET command is encountered. The next two ACCEPTs are not reached in such case. -------------------- The READNEXT Command -------------------- FORMAT: READNEXT [value comparator value] NOTE: For an explanation of comparators, see the section "Comparators". In the following explanation, we will demonstrate the command using only the "equals" ("=") comparator. The READNEXT command gets the next line of the input file (in other words, it replaces the current $FLINE), while maintaining your place in the POM file. This is helpful if you know for certain what the next line will contain. Here is an example: SET note = "" SET customer = $FLINE[1 20] BEGIN $FLINE ^ "See note below" READNEXT SET note = $FLINE[1 20] END OUTEND |{customer} {note} If the input line contains the words "See note below", Parse-O-Matic will read the next line of the input file (replacing the current $FLINE), thus obtaining the comment about the customer. When you do a READNEXT, there is no way to return to the previous line of the input file. If you need it for other work, you should save a copy: SET note = "" SET customer = $FLINE[1 20] SET saveline = $FLINE BEGIN $FLINE ^ "See note below" READNEXT SET note = $FLINE[1 20] END SET custnum = saveline[22 25] OUTEND |{custnum} {customer} {note} The example above is not very efficient; it would make more sense to extract custnum BEFORE you use READNEXT. However, in some instances you may find it more convenient to save $FLINE before doing a READNEXT. READNEXT can make a comparison. This is useful for skipping extraneous lines of input. For example: READNEXT $FLINE[1 5] = "NOTE:" This obtains the next input line if the current input line starts with "NOTE:". =========================================================================== VARIABLE MODIFIERS =========================================================================== COMMAND DESCRIPTION ------- ----------- TRIM Removes a character from the left, right or all of a variable PAD Centers, or left/right-justifies variable to a specified width CHANGE Replaces all occurances of a string in a variable PROPER Properizes a variable (e.g. "JOHN SMITH" becomes "John Smith") INSERT Inserts a string on the left or right, or at a "found" position APPEND Concatenates several variables into one variable ---------------- The TRIM Command ---------------- FORMAT: TRIM var1 spec1 character TRIM removes characters from var1. This is usually used to remove blanks. spec1 can be: A=All B=Both ends L=Left side only R = Right side only For example: SET PRICE = $FLINE[20 26] TRIM PRICE "A" "," TRIM PRICE "L" "$" This removes all commas from the variable "PRICE", and removes the leading dollar sign. Thus: If the input contains the string: "$25,783" The first TRIM changes it to: "$25783" The second TRIM changes it to: "25783" --------------- The PAD Command --------------- FORMAT: PAD var1 spec1 character len PAD makes var1 a specified length, padded with a specified character. spec1 is "L", "R", or "C" (Left, Right or Center) character is the character used to pad the string len is the desired string length For example, if the variable ABC is set to "1234" ... PAD ABC "L" "0" "7" left-pads it 7 characters wide with zeros ("0001234") PAD ABC "R" " " "5" right-pads it 5 characters wide with spaces ("1234 ") PAD ABC "C" "*" "8" centers it, 8 wide, with asterisks ("**1234**") If the length is less than the length of the string, it is unchanged. For example, if you set variable XYZ to "PINNACLE", then PAD XYZ "R" " " "3" leaves the string as-is ("PINNACLE"). Thus, PAD can not be used to shorten a string. If it is your intention to make XYZ 3 letters long, you can use the SET command: SET XYZ = XYZ[1 3] ------------------ The CHANGE Command ------------------ FORMAT: CHANGE var1 value1 value2 The CHANGE command replaces ALL occurances of value1 with value2. This is more powerful than TRIM, but is not as efficient. Here is an example of the CHANGE command in action: SET DATE = $FLINE[31 38] CHANGE DATE "/" "--" If the SET command assigns DATE the value: "93/10/15" Then the CHANGE command converts it to: "93--10--15" ------------------ The PROPER Command ------------------ FORMAT: PROPER var1 [methods [exceptions-file]] The PROPER command converts uppercase text (LIKE THIS) to mixed-case text (Like This). This is useful when you have a list of names of people and addresses. You can also use PROPER to change text that has been typed in uppercase into normal text, with capital letters at the beginning of sentences. The simplest way to convert a variable is as follows: PROPER CustName If CustName contains "JOHN SMITH", it will be changed to "John Smith". The conversion routine is fairly intelligent. For example, if it is converting the words "JAGUAR XJS", it can tell that XJS is not a word (since it does not contain any vowels) and so the the end result will be "Jaguar XJS". Other "strange-looking" items such as serial numbers can often be recognized by the PROPER command, and left untouched. Nevertheless, it is impossible to handle all situations, so the PROPER command supports a "Properization Exceptions File" (known as a PEF file). A PEF file lists unusual combinations of letters (typically abbreviations, such as Dr.). The Parse-O-Matic package includes a file named GENERIC.PEF, which you may find helpful. You can view it with the SEE program provided with Parse-O-Matic. A PEF file is prepared with a text editor and contains one "exception" per line. Null or blank lines, or lines that start with a semicolon, are ignored. The longest word that can be specified is 255 characters. Spaces are permitted, but leading and trailing spaces and tabs are ignored. To use the PEF file in your PROPER command, place the file name after the variable name and method setting. For example: PROPER CustName "W" "GENERIC.PEF" The "W" is the method setting (explained later). "GENERIC.PEF" is the name of the PEF file. When Parse-O-Matic looks for the PEF file, it looks first in the current directory. If it can not find it there, it looks in the directory where POM.EXE is located. You can, if you wish, specify a complete path to the file, as in this example: PROPER Address "W" "C:\MYFILES\MYPEF.XYZ" If you don't need an exceptions file, you should not use it, since it slows down processing somewhat. Needless to say, the more items you have in the PEF file, the more it slows down processing. The method setting allows you to specify what PROPER does. There are several kinds of controls, as follows: METHOD DESCRIPTION ------ ----------- I Intelligent determination of non-words S Upcase the first character of each sentence U Upcase the first alphanumeric character of the line W Upcase the first letter of each word The default method setting is "IW", so if you omit the method setting, or specify a null setting (e.g. PROPER CustName "" "XYZ.PEF"), PROPER will upcase non-words, and the first letter of each word. NOTE: If you specify a PEF file, you must also specify a method setting, even if it is null. The line PROPER "GENERIC.PEF" would not be understood by Parse-O-Matic. The correct format would be: PROPER "" "GENERIC.PEF" The examples provided with Parse-O-Matic demonstrate some ways you can use the PROPER command. To see the examples, enter START at the DOS prompt, then select TUTORIAL. ------------------ The INSERT Command ------------------ FORMAT: INSERT var1 spec1 value1 The INSERT command inserts text on the left or right of var1, or at a "found text" position. spec1 is "L" or "R" (Left or Right) or a find-string (e.g. "@HELLO") value1 is the value to be inserted For example, if the variable ABC is set to "Parse-O-Matic", then INSERT ABC "L" "Register " sets ABC to "Register Parse-O-Matic" INSERT ABC "R" " is super" sets set ABC to "Parse-O-Matic is super" You can use a find-string to insert text at the first occurance of the text you specify. For example: INSERT ABC "@-O-Matic" "!" sets ABC to "Parse!-O-Matic" If the find-string is not found, nothing is done. For an alternative to INSERT, see the APPEND command. ------------------ The APPEND Command ------------------ FORMAT: APPEND var1 value1 value2 [value3 [value4]] The APPEND command concatenates (adds together) two or more values and places the result in var1. For example: APPEND xyz "AB" "CD" "EF" "GHIJ" This command sets the variable xyz to "ABCDEFGHIJ". The third and fourth values (value3 and value4 in the FORMAT shown above) are optional. Thus, you can use APPEND with only two values. For example: SET x1 = "AB" SET x2 = "CD" APPEND x3 x1 x2 This sets the variable x3 to "ABCD". You can concatenate a maximum of four values with a single APPEND command. If you require additional concaten- ations, you can use more APPEND commands: APPEND myvar "ABC" "DEF" "GHI" "JKL" APPEND myvar myvar "MNO" "PQR" The first line sets the variable myvar to "ABCDEFGHIJKL". The second line set myvar to its previous value, plus "MNOPQR", so that its final value is "ABCDEFGHIJKLMNOPQR". NOTE: No variable can hold more than 255 characters. =========================================================================== INPUT PREPROCESSORS =========================================================================== COMMAND DESCRIPTION ------- ----------- SPLIT Breaks up a wide text file (more than 255 characters) CHOP Breaks up a fixed-record-length file ----------------- The SPLIT Command ----------------- FORMAT: SPLIT from-position to-position [,from-pos'n to-pos'n] [...] The maximum length of an input line from a text file is 255 characters. If your input file is wider than that, you must break up the file into manageable chunks, using the SPLIT command. This command lets you specify the way in which each input line is broken up so that it will look like several SEPARATE lines. For example, if your input lines were up to 300 characters wide, you could specify: SPLIT 1 255, 256 300 This breaks up each line as if it was two lines. (If some of the lines are less than 256 characters, they will still be treated as two lines, although the second line will be null (i.e. empty).) You can specify up to 100 splits (use multiple SPLIT commands if necessary). With SPLIT, Parse-O-Matic can handle input records of up to 32767 characters. The best way of handling SPLIT or CHOPped files is to use a combination of $SPLIT (explained in more detail later) and BEGIN/END. For example: SPLIT 1 250, 251 300 BEGIN $SPLIT = "1" SET a = $FLINE[ 1 10] SET b = $FLINE[11 20] END BEGIN $SPLIT = "2" SET x = $FLINE[ 1 10] SET y = $FLINE[11 20] OUTEND |{a} {b} {x} {y} END This outputs the data which appears (in the input file) in columns 1-10, 11-20, 251-260 and 261-280. ---------------- The CHOP Command ---------------- FORMAT: CHOP from-position to-position [,from-pos'n to-pos'n] [...] The CHOP command works the same way as the SPLIT command, with one exception: it informs Parse-O-Matic that the input is a fixed-record- length file. In other words, it means that the input records are distinguished by having a particular (and exact) length, rather than being separated by end-of-line characters (Carriage Return, Linefeed) as is the case for a standard text file. Thus, if you have an input file containing fixed-length records, each of which is 200 characters wide, you could specify it like this: CHOP 1 200 If the input record is more than 255 characters, you must break it up into smaller chunks. For example, if the input record was 300 characters wide, you could break it up like this: CHOP 1 250, 251 300 By using CHOP, Parse-O-Matic can handle input records up to 32767 characters wide. You can use the $SPLIT variable to manage your use of CHOP. See the example in the section describing the SPLIT command. =========================================================================== LOOKUP COMMANDS =========================================================================== COMMAND DESCRIPTION ------- ----------- LOOKUP Looks up a word in another file and returns a corresponding value LOOKFILE Specifies the file that the LOOKUP command will use (see also /L) LOOKCOLS Specifies the format of the look-up file LOOKSPEC Controls the behaviour of the LOOKUP command ------------------ The LOOKUP Command ------------------ FORMAT: LOOKUP var1 value1 The LOOKUP command will search for value1 in a text file (the name of which is specified either by the LOOKFILE command or the /L startup parameter). When POM finds it, it sets var1 to another value found on the same line. Let us suppose you created a text file, named NAMES.TBL, like this: R. REAGAN Ronald Reagan D. EISENHOWER Dwight Eisenhower G. BUSH George Bush : : Column 1 Column 18 This file can be used to look up a name, as in this POM file: LOOKFILE "NAMES.TBL" LOOKCOLS "1" "17" "18" "34" SET oldname = $FLINE[21 37] TRIM oldname "R" " " LOOKUP newname = oldname OUTEND |{oldname} {newname} The LOOKFILE command specifies the name of the look-up file. The LOOKCOLS command specifies the starting and end columns for both the "text-to-look- for" field (known as the key field) and the "text-to-replace-with" field (known as the data field). The LOOKUP command will look for oldname in NAMES.TBL. If oldname is set to "G. BUSH", LOOKUP sets newname to "George Bush". If, however, oldname is set to "G. WASHINGTON", which doesn't appear in NAMES.TBL, newname is set to "" (that is to say, an empty string). There is no limit to the number of lines that you can put in a look-up file. However, the more lines there are, the longer it will take to process (because there is more to search). The maximum length of a line in a look-up file is 255 characters. In the look-up file, null (empty) lines are ignored. You can also include comments in the file by starting the line with a semi-colon: ; Some of the Presidents of the United States R. REAGAN Ronald Reagan D. EISENHOWER Dwight Eisenhower G. BUSH George Bush The LOOKUP command can be used for more than just names, of course. You could use it to look up prices, phone numbers, addresses and so on. -------------------- The LOOKFILE Command -------------------- FORMAT: LOOKFILE value1 The LOOKFILE command specifies the name of the look-up file for the next LOOKUP command. This lets you use several look-up files in one POM file. For example: SET name = $FLINE[1 20] ; Look up full name LOOKFILE "NAMES.TBL" LOOKCOLS "1" "25" "30" "50" LOOKUP fullname = name ; Look up phone number LOOKFILE "PHONE.TBL" LOOKCOLS "1" "25" "30" "40" LOOKUP phone = name ; Output result OUTEND |{name} {fullname} {newname} If you only have one look-up file, you may omit the LOOKFILE command and specify the file name on the command line, using the /L parameter. For example, you could write a POM file like this: SET name = $FLINE[1 20] ; Look up full name LOOKCOLS "1" "25" "30" "50" LOOKUP fullname = name ; Output result OUTEND |{name} {fullname} Your POM command could then look like this: POM MYPOM.POM INPUT.TXT OUTPUT.TXT /LC:\MYFILES\NAMES.TBL This technique allows you to use several different look-up files with the same POM file, simply by changing the command line. -------------------- The LOOKCOLS Command -------------------- FORMAT: LOOKCOLS value1 value2 value3 value4 The LOOKCOLS command specifies the starting and ending columns for the key and data fields in a look-up file (see the explanation of the LOOKUP command for an overview of look-up files). value1 specifies the starting column for the key field value2 specified the ending column for the key field value3 specifies the starting column for the data field value4 specified the ending column for the data field You can specify a null value to indicate "same as last time". For example: SET name = $FLINE[1 20] LOOKFILE "NAMES.TBL" LOOKCOLS "1" "25" "30" "50" LOOKUP fullname = name LOOKFILE "PHONE.TBL" LOOKCOLS "" "" "" "40" LOOKUP phonenum = name OUTEND |{name} {fullname} {phonenum} The second LOOKCOLS command uses the same numbers for the first three values that the first LOOKCOLS command used. If you do not specify a LOOKCOLS command, the default values are: Key Field: Starting column = 1 Ending column = 10 Data Field: Starting column = 12 Ending column = 255 This is equivalent to LOOKCOLS "1" "10" "12" "255". -------------------- The LOOKSPEC Command -------------------- FORMAT: LOOKSPEC value1 value2 value3 The LOOKSPEC command configures the way the next LOOKUP command will work. value1 = Trim ("Y" or "N" -- default "Y") value2 = Sorted ("Y" or "N" -- default "N") value3 = Case-sensitive ("Y" or "N" -- default "N") The Trim setting specifies whether or not the data field should have spaces stripped off both ends. The Sorted setting specifies whether or not the look-up file is sorted by the key field. A sorted file is much faster than an unsorted file. This is especially noticeable if you have a large look-up file and a lot of input to process. The Case-sensitive setting specifies whether or not LOOKUP should distin- guish between upper and lower case when searching. The default setting is "N" (No), so that LOOKUP would find "John Smith", even if it appeared in the look-up file as "JOHN SMITH". It is usually safest to set Case- sensitivity to "N", but if you set it to "Y", searching is slightly faster. You can specify a null value to indicate "same as last time". For example: SET name = $FLINE[1 20] LOOKFILE "DATA.TBL" LOOKCOLS "1" "25" "30" "50" LOOKSPEC "Y" "Y" "Y" LOOKUP fullname = name LOOKCOLS "" "" "60" "70" LOOKSPEC "N" "" "" LOOKUP phonenum = name OUTEND |{name} {fullname} {phonenum} The second LOOKSPEC command uses the same settings for Sorted and Case- sensitivity as the first one, but specifies a different Trim setting. =========================================================================== MISCELLANEOUS COMMANDS =========================================================================== COMMAND DESCRIPTION ------- ----------- TRACE Traces a variable (results saved in the text file POM.TRC) SETLEN Sets a variable according to the length of a value SOUND Makes a noise or sets the noise generated by error messages ----------------- The TRACE Command ----------------- FORMAT: TRACE var1 The TRACE command is an alternative to standard tracing (see "Tracing", in the "Terms and Techniques" section). When you include a TRACE command in your POM file, Parse-O-Matic will create a text file, named POM.TRC, and use it to keep a detailed record of POM's processing. Here is an example of the TRACE command: TRACE PRICE This traces the variable named "PRICE". After processing, the file POM.TRC will show everything that happened, and give the value of PRICE at the TRACE line. NOTE: Since trace files are so detailed, they can be very large. If you are trying to debug a POM file using TRACE, it is a good idea to use a small input file. ------------------ The SETLEN Command ------------------ FORMAT: SETLEN var1 value1 SETLEN sets var1 to the length of value1. For example: SET x = "ABCD" SETLEN y x This sets variable y to "4". One handy application for SETLEN is to underline text. For example: SET name = $FLINE[1 15] TRIM name "B" " " SETLEN nlen name SET uline = "" PAD uline "L" "-" nlen OUTEND |{name} OUTEND |{uline} If the input line contains the name "JOHN SMITH", the output would be: JOHN SMITH ---------- For another example of underlining, see "POM and Wildcards". ----------------- The SOUND Command ----------------- FORMAT: SOUND value The SOUND command performs two functions: 1) It makes a noise, or ... 2) It sets the noise made when an error occurs The SOUND command has a repetoire of nine distinctive noises: BEEP BIP BUZZ EDGE ERROR HUH PIP TRILL WHOOP These sounds are useful for alerting you to unusual situations. Let's say you wanted to be warned if one of the fields in a file comes up blank. You could write the code this way: BEGIN lastname = "" SOUND "WHOOP" SET lastname = "?" END Case is not important; the following commands are all equivalent: SOUND "WHOOP" SOUND "Whoop" SOUND "whoop" You can listen to any given sound by using the LISTEN command at the DOS prompt. To hear what TRILL sounds like, enter this command: LISTEN trill By default, Parse-O-Matic error messages will alert you by playing the ERROR sound. To hear this sound, enter the following command at the DOS prompt: LISTEN error If you find this noise annoying, you can replace it with one of the other sounds by using the special ERRMSG specification of the SOUND command. For example, to replace the ERROR sound with the BUZZ sound, place this line at the top of your POM file: SOUND "ERRMSG BUZZ" If you don't want any sound made when an error occurs, use this command: SOUND "ERRMSG QUIET" The ERRMSG specification will only affect errors generated during the actual running of the POM file. If an error is encountered while Parse-O-Matic is compiling, it will use the ERROR sound when it reports the problem. =========================================================================== TERMS AND TECHNIQUES =========================================================================== ------ Values ------ A value can be specified in the following ways: "text" A literal text string #number A single ASCII character (e.g. #32 = Space) #number#number... Several ASCII characters (e.g. #32#32 = 2 Spaces) VARNAME The name of a variable VARNAME[start end] A substring of a variable VARNAME[start] A single character VARNAME+ Incremented variable (see explanation below) Variable names can be up to 8 characters long. There is no distinction between upper and lower case in the variable name. A POM file can contain about 1000 variables and literals. The # character is used to specify a literal text string of one or more characters. Follow each # with the decimal value of the ASCII character you want. Here are some useful values: #10 = Line Feed #12 = Form Feed #13 = Carriage Return Parse-O-Matic predefines several variables. They are: $FLINE = The line just read from the file (max. length 255 chars) $FLUPC = The line just read from the file, in uppercase $BRL = The { character (used in OUT) $BRR = The } character (used in OUT) $COMMAND = The current POM command line (see "POM and Wildcards") $SPLIT = The CHOP or SPLIT number you are currently processing $TAB = The tab character (Hex $09; ASCII 09) Since $FLINE has a maximum length of 255 characters, you will have to use the SPLIT or CHOP command if your input file is wider than that. The $SPLIT variable reports which segment you are processing. For example, if you had this command... CHOP 1 255, 256 380 then $SPLIT would be set to "1" when it was processing columns 1 to 255, and it would be set to "2" when it was processing columns 256 to 380. ---------- Delimiters ---------- If you need to specify a quotation mark, use "". For example: IGNORE $FLINE = "He said ""Hello"" to me." This ignores any line containing: He said "Hello" to me. ------------------ Illegal Characters ------------------ No command can contain these ASCII characters: HEX DECIMAL NAME --- ------- -------------------- $00 0 NULL $0A 10 LF (Linefeed) $0D 13 CR (Carriage Return) Of course, LF and CR do appear at the end of each line, in a text file. ----------- Comparators ----------- The ACCEPT, BEGIN, IF, IGNORE, OUT and OUTEND commands each decide what to do by comparing two values. For example: IF $FLINE[1 3] = "XYZ" THEN x = "3" ELSE "4" In this example, if the first three characters of $FLINE are "XYZ", the variable x is set to "3", otherwise it is set to "4". The first equals sign ("=") is a "comparator", because it defines how two values will be compared. The second equals sign is not a comparator; it is simply padding, which makes the line easier to understand (see the section "Padding for Clarity" for details). Parse-O-Matic allows the following comparators: COMPARATOR MEANING EXAMPLE ---------- ------------------ --------------------------------------------- <> Does not equal IF name <> "Fred" THEN z = "This is not Fred" = Equals IF numeral = "IV" THEN x = "4" > More than IF x > "4" THEN z = "x is more than four" >= More than or equal IF x >= "4" THEN z = "x is four or more" < Less than IF x < "4" THEN z = "x is less than four" <= Less then or equal IF x <= "4" THEN z = "x is four or less" ^ Contains IF x ^ "4" THEN z = "x contains a four" ~ Does not contain IF X ~ "4" THEN z = "x doesn't contain four" LONGER Length is longer IF x LONGER y THEN z = "x is longer than y" SHORTER Length is shorter IF x SHORTER y THEN z = "x is shorter than y" SAMELEN Length is the same IF x SAMELEN y THEN z = "Same length as y" Whenever a comparator is required, but is omitted, it is assumed to be "equals". Thus, the following lines are equivalent: IF x y z "3" "4" (This is very terse, but it works) IF x y THEN z = "3" ELSE "4" (The "equals" comparator is omitted) IF x = y THEN z = "3" ELSE "4" (This is a lot easier to read) Comparators work on numeric and alphabetic data. Here are some samples: "ABC" <> "ABCD" "3" <> "4" "ABC" <= "ABCD" "3" <= "4" "ABC" < "ABCD" "3" < "4" "ABC" SHORTER "ABCD" "3" SAMELEN "4" "ABC" >= "ABC" "ABC" <> "CDE" "ABC" <= "ABC" "ABC" <= "CDE" "ABC" = "ABC" "ABC" < "CDE" "ABC" ^ "ABC" "ABC" SAMELEN "CDE" "ABC" SAMELEN "ABC" IF YOU USED PARSE-O-MATIC PRIOR TO VERSION 3.00: Because the comparator defaults to "equals" if it is omitted, POM files created before version 3.00 will continue to function normally -- with two notable exceptions. In older versions, the IGNORE and ACCEPT commands defaulted to "contains". If you have POM files that were created for older versions, you should check your IGNORE and ACCEPT commands to ensure that they are doing what you want them to. ------------ Incrementing ------------ You can add "1" to a variable in a SET statement. For example: SET x = "3" SET x = x+ After the second statement, x would have the value "4". Only numeric incrementing is supported. Attempting to increment another type of variable will result in an error. - Incrementing "1" gives you "2" - Incrementing "9" gives you "10" The first time a variable is referenced, it has a null value (unless you SET it yourself). If you increment a null variable, it will be changed from "" (i.e. null) to "1". ------------- Line Counters ------------- If your input record is divided over several lines (due to its original format or perhaps because you used the SPLIT or CHOP command), it is helpful to set up a line counter. The following example extracts the first six characters of the second line of input records that span three lines (designated lines 0, 1 & 2): IF LineCntr = "1" THEN MyField = $FLINE[1 6] OUTEND LineCntr = "1" |{MyField} IF LineCntr = "2" THEN LineCntr = "" ELSE LineCntr+ For an alternative to line counters, see "The READNEXT Command". ------- Tracing ------- By setting the DOS variable POM to ALL, you can generate a trace file, named POM.TRC. This is helpful if you have trouble understanding why your file isn't being parsed properly. But be sure to test it with a SMALL input file; the trace is quite detailed, and it can easily generate a huge output file. To save space, you can specify a particular list of variables to be traced, rather than tracing everything. For example, to trace only the variable PRICE, enter this DOS command: SET POM=PRICE To trace several variables, separate the variable names by slashes, as in this example: SET POM=PRICE/BONUS/NAME This traces the three variables PRICE, BONUS and NAME. ------- Logging ------- Every time Parse-O-Matic runs, it creates a text file named POMLOG.TXT in its home directory. (For example, if POM.EXE is located in C:\POM, the file will be C:\POM\POMLOG.TXT even if you run POM from another directory.) If the file POMLOG.TXT already exists, it is renamed to POMLOG.BAK. The logging file POMLOG.TXT contains a report of what happened during the last run of Parse-O-Matic. Usually, the file will be quite short and look something like this: COMMAND: POM TEST.POM TEST.TXT TEMP.TXT DATE: JAN 01 1995 17:50:10 TEST.TXT opened for processing 17:50:14 TEST.TXT processing completed The first line gives the DOS command line, while the second gives the date. Subsequent lines give the time (Hours:Minutes:Seconds) and a progress or error message. If you encounter an error during processing, the text of the warning message is saved in the logging file. It might look something like this: COMMAND: POM TEST.POM TEST.TXT TEMP.TXT DATE: JAN 01 1995 17:50:10 TEST.TXT opened for processing 17:50:10 Execution error in line number 3 of POM file TEST.POM 17:50:11 Required parameter is missing in OUT If you process multiple input files, POMLOG.TXT might look something like this: COMMAND: POM EXAMPL15.POM DATA*.TXT TEMP.TXT DATE: JAN 01 1995 14:21:27 DATA01.TXT opened for processing 14:21:28 DATA01.TXT processing completed 14:21:28 DATA02.TXT opened for processing 14:21:28 DATA02.TXT processing completed 14:21:28 DATA03.TXT opened for processing 14:21:28 DATA03.TXT processing completed If for some reason the log file can not be created, Parse-O-Matic will continue to run; it will not terminate. For some additional comments on logging, see "Unattended Operation". ---------- Quiet Mode ---------- Sometimes you don't want the user to see the Parse-O-Matic processing screen. In such cases, you can use the "Quiet Mode" switch (/Q) on the command line. For example: POM XYZ.POM MYFILE.TXT TEMP.TXT /Q The /Q switch suppresses the display of the processing screen. The only time a user will see anything is if there is a problem (for example: the input file was not found). --------- DbF Files --------- If Parse-O-Matic notices that the input file is a "DBase" file (i.e. it has a DBF extension -- for example: MYFILE.DBF), it will change the way it processes the data. For instance, the variable $FLINE is not defined. Rather, each of the fields in the database are pre-parsed. Thus, if you have a DBF file containing three fields (EMPNUM, NAME, PHONE), your entire POM file might look like this: IGNORE DELETED "Y" OUTEND |{EMPNUM} {NAME} {PHONE} The DELETED variable is created automatically for each record. If it is set to "Y", it means the record has been deleted from the database and is probably not valid. In most cases, you will want to ignore such records. If you do not know what the field names are, you can obtain the list with the following POM file: TRACE DELETED Afterwards, when you inspect the trace file (POM.TRC), you will see a summary of all the fields. Since there are no output commands (e.g. OUTEND and OUTHDG), the output file will be empty. NOTE: Parse-O-Matic does not currently support DBF "Memo" fields. ----------------- POM and Wildcards ----------------- You can process multiple input files with the same POM file by specifying a DOS "wildcard" at the DOS command prompt. All output is then directed to the same output file. For example: POM XYZ.POM *.TXT OUTPUT.TXT This runs XYZ POM.file on each file in the current directory with a TXT extension and sends all output to the file OUTPUT.TXT. The POM file can determine which file it is reading by using the predefined variable $COMMAND, which contains the current POM command line. Consider the following scenario: - You have installed POM.EXE in the directory path C:\UTILITY\POM - The current directory contains ABC.POM, MARK.TXT, MARY.TXT and JOHN.TXT - You enter the command POM ABC *.DAT OUT.TXT Parse-O-Matic runs ABC.POM against the three TXT files. On the first input file, $COMMAND will look like this: C:\UTILITY\POM.EXE ABC.POM MARK.TXT OUT.TXT On the next two input files, it looks like this: C:\UTILITY\POM.EXE ABC.POM MARY.TXT OUT.TXT C:\UTILITY\POM.EXE ABC.POM JOHN.TXT OUT.TXT Note that the file OUT.TXT is NOT processed, even though it has a TXT extension. POM will always avoid processing the output file. Let's say you wanted to concatenate both MARK.TXT and MARY.TXT, and put the file name at the top. You could do it with this POM file, named ABC.POM: SET cmd = $COMMAND <--- Get the command line BEGIN cmd <> lastcmd <--- Has it changed? PARSE fname cmd "2* " "3* " <--- Extract the input file name SETLEN flen fname <--- Get length of input file name SET uline = "" <--- Initialize underline PAD uline "L" "-" flen <--- Set underline OUTEND lastcmd <> "" | <--- Output a linefeed unless this OUTEND lastcmd <> "" | <--- is the first file OUTEND |{fname} <--- Output the file name OUTEND |{uline} <--- Output the underline OUTEND | <--- Output a linefeed SET lastcmd = $COMMAND <--- Remember this command line END <--- End of code block OUTEND |{$FLINE} <--- Output a line from the input You could then process MARK.TXT and MARY.TXT with this command line: POM ABC M*.TXT OUT.TXT This processes any file starting with an "M" that has a TXT extension. Another way to run the command is as follows: POM ABC M???.TXT OUT.TXT This processes any four-letter TXT file that starts with "M". For more information about DOS wildcards, consult your DOS manual. =========================================================================== OPERATIONAL PLANNING =========================================================================== -------------------- Unattended Operation -------------------- Several features have been built in to Parse-O-Matic to enable "unattended operation". That means that you can design applications that run themselves while you are not there. There are two reasons why you might want to do this: - You can run long processing jobs just before leaving work at night - Parse-O-Matic is useful, but it isn't very interesting to watch! There are several features which facilitate unattended operation: - The SOUND command can alert you if something unusual happens - All error messages (which say "Press spacebar to continue") will "time-out" (i.e. continue) after about a minute - The log file (see "Logging") can be used to check processing Let's say you wanted to concatenate (add together) several enormous text files. You could start with the following POM file (named ADD.POM): SET cmd = $COMMAND BEGIN cmd <> lastcmd SOUND "BEEP" SET lastcmd = cmd END OUTEND |{$FLINE} You could then enter the command POM ADD.POM *.TXT ALL.TXT and walk away. Whenever a new file is started, you'll hear a beep. When you come back, you can check the file POMLOG.TXT (which will be located in the same directory as POM.EXE). It might look something like this: COMMAND: POM ADD.POM *.TXT ALL.TXT DATE: JAN 01 1995 16:39:12 JOHN.TXT opened for processing 16:45:28 JOHN.TXT processing completed 16:45:29 MARY.TXT opened for processing 16:52:10 MARY.TXT processing completed 16:52:11 FRED.TXT opened for processing 17:03:33 FRED.TXT processing completed If you are processing multiple files, and each one uses a different POM file (and hence requires a separate run of Parse-O-Matic) you can write your batch file so that it renames the log files. This lets you review each log file later. For example: @ECHO OFF POM JOHN.POM JOHN.TXT JOHN.LST RENAME C:\POM\POMLOG.TXT JOHN.LOG POM MARY.POM MARY.TXT MARY.LST RENAME C:\POM\POMLOG.TXT MARY.LOG POM FRED.POM FRED.TXT FRED.LST RENAME C:\POM\POMLOG.TXT FRED.LOG When processing is complete, the files JOHN.LOG, MARY.LOG and FRED.LOG will be available in the directory C:\POM for your inspection. Here is a slightly more sophisticated version of the batch file: @ECHO OFF POM JOHN.POM JOHN.TXT JOHN.LST IF ERRORLEVEL 1 GOTO QUIT RENAME C:\POM\POMLOG.TXT JOHN.LOG POM MARY.POM MARY.TXT MARY.LST IF ERRORLEVEL 1 GOTO QUIT RENAME C:\POM\POMLOG.TXT MARY.LOG POM FRED.POM FRED.TXT FRED.LST IF ERRORLEVEL 1 GOTO QUIT RENAME C:\POM\POMLOG.TXT FRED.LOG :QUIT The IF ERRORLEVEL lines jump to the end of the batch file if Parse-O-Matic generates an error of 1 or higher. (The IF ERRORLEVEL command in batch files is considered "True" if the error is the specified value or higher.) -------------------------------- Converting Comma-Delimited Files -------------------------------- As explained in the section "The PARSE Command", Parse-O-Matic can convert comma-delimited files to columnar format. However, if you are frequently faced with this task, you may find it easier to use Pinnacle Software's CCDF utility. You can download a copy from our free files BBS at 514-345-8654. (Sign on as GUEST -- no password needed -- and enter the command GET CCDF to start downloading the file CCDF.ZIP. The default download protocol is ZMODEM, but you can change this with the PROTOCOL command.) -------- Examples -------- Most of the techniques described in this manual are demonstrated by the examples provided with the standard Parse-O-Matic package. To see these examples, switch to your Parse-O-Matic directory, type START at the DOS prompt, then select TUTORIAL. =========================================================================== LICENSING =========================================================================== This product is available in several forms: TRIAL LICENSE: If you have a "test-drive" evaluation copy, you will see a "Registration Reminder Screen" when you start up the program. You are entitled to evaluate this program at no cost for up to 45 days. If you continue to use it after that, you are required to purchase a registered copy (see below). REGISTERED: When you register an evaluation copy of this product, you will receive the latest version, plus an unlocking code that will let you register any new evaluation versions that we release for a period of two years. The file OPTIONS.DOC explains the various payment methods available. A registered copy provides you with a single-user license. SITE/MULTI-COPY LICENSES: If you plan to run 15 or more copies of this program simultaneously (on a network or on separate computers), you can obtain quantity pricing. See the order form (file ORDER.FRM) for details. DISTRIBUTION LICENSE: The distribution license ($750) allows you to use an unlimited number of copies of a specially personalized copy. You may include it in a commercial package as a utility. The only restriction is that you may not distribute this document (i.e. the user manual) or its essential content. With this safeguard, we avoid placing ourselves in competition with you; the program must be used to support a product rather than being a main selling feature. RETAIL LICENSE: You can sell complete, registered copies of this product, complete with documentation, in return for royalties. The terms depend on volume and advance payments. The license is $100 plus the following royalty scale: Non-exclusive, prepayment for 1,000 copies ------------------- $1.00/copy Non-exclusive, prepayment for 5,000 copies ------------------- $0.50/copy Non-exclusive, prepayment for 10,000 copies ------------------- $0.30/copy Non-exclusive, prepayment for 25,000 copies ------------------- $0.20/copy Non-English exclusive, 10,000 copy prepayment ----------------- $0.35/copy Non-English exclusive, 25,000 copy prepayment ----------------- $0.25/copy In the above rate schedule, packaging, product duplication and support are the responsibility of the retailer. For non-English versions, we have a team available which can handle language conversions (this service is priced separately). If you wish to obtain a retail license, please contact us to request the retail license contract appropriate to your requirements.