Fast Tables (table.lsp)


With so many drawings containing tables of one sort or another these days, I'm a little surprised that I haven't come across a simple table routine. So I wrote one.

The Listing

After the program description, the program’s name is defined and the variables it uses are localized. The values of the CMDECHO and BLIPMODE Setvars are then saved in variables CMD2 and BM2 to be used for restoration later as the program will be changing them.

The INITGET function is then used to initialize the permissible user responses to the following GETKWORD function which saves the response (table justification) to the TJ2 variable. We then use a little-known technique of mapping a function to a variable according to whether the table is left or right justified. Here the addition function is mapped to OP2 if the table is left justified and the subtraction function is mapped to OP2 if not. This is used to reduce the amount of code required later on when building up new points lists - we don't have to continually check the justification.

The same is done for top and bottom justification with subtraction being mapped to OP3 if the table is top justified and addition being mapped to OP3 if it is not.

We then move into a series of user input prompts to get the required information, each of which use the INITGET function with the "1" argument to ensure that the user does provide some data. We start by getting the relevant corner point of the table, storing it in variable PT2. This is followed by a request for the height of the primary (or first) row. Note that the GETDIST function was used rather than GETREAL and PT2 was an argument to it; this enables the user to provide a distance by picking a point on the screen relative to PT2 with the rubber-band line visible.

The next line generates a point list to define the boundary between the primary and secondary rows. Evaluating it from the inside out, the LIST function creates a list of 3 numbers: zero, the primary row height and zero. This is returned to the MAPCAR function that creates a new list by running the function mapped into the OP3 variable and pairing off the elements in the list stored in PT2 and the list just created by the LIST function.

As an example, take PT2 as (50.0 40.0 0.0), the height of the primary column as 5 and the subtraction operator mapped to OP3. The LIST function will return the list (0.0 5.0 0.0) and MAPCAR will pair off the elements of each list and subtract them as below:

50.0 - 0.0 = 50.0

40.0 - 5.0 = 35.0

0.0 - 0.0 = 0.0

This creates a new list, (50.0 35.0 0.0), that represents a point 5 drawing units below PT2. This list is stored in variable PT3.

This point is then used in the next prompt for the height of the secondary rows to bring up the rubber-band line when dragging the distance. This height is stored in variable HT3

The user is then prompted for the number of secondary rows using GETINT to force an integer, and then the width of the first column, giving the user the ability to drag the distance. A point list is then generated as before except that OP2 is used instead of OP3 and then stored in variable PT4. The width of the column is then also put into a list that is stored in variable CL2.

We then enter a WHILE loop that continues as long as WD2 has a value. This prompts for the next column width, saving it to WD2 and overwriting the previous value, and then enters into an IF that runs if WD has a value. This adds the new column width to the list in CL2 and creates a new point for PT4 allowing the user to drag the column width for the "Next column width:" prompt for the next interation through the loop. Once the user hits <RETURN> to this prompt, WD2 will have no value and the WHILE loop will end.

We then start an IF which checks for the horizontal justification (left or right) of the table by checking the value in OP3 and then calculates the total width of the table accordingly; positive for left justification and negative for right justification. After ending this IF, another is started that determines the total height of the table according to its vertical justification. These distances are stored in variables HDIST2 and VDIST2 respectively.

A SETQ function will then set the other three corner points of the table and the start point for the line dividing the primary and secondary rows. The MAPCAR function is used to add the pairs of numbers in the two lists to produce the corner point diagonally opposite the start corner. This is stored in variable PT5. Variable PT6 is then set to a point aligned horizontally with PT2 and vertically with PT5 by building up a point list from the X value of PT2 and the Y value of PT5. Variable PT7 is then set to a point aligned horizontally with PT5 and vertically with PT2. Variable PT8 is then set to the end of the divider line between the primary and secondary rows that is directly below or above PT2 (depending on justification).

We are now just about ready to start drawing some lines but first we need to prepare a couple of things. We start by turning off the blips and suppressing command echoing. Then an Undo group is started so the entire table can be deleted with a single U command. Since R13, the Group option for Undo has been replaced by BEgin but Group still seems to be supported.

The COMMAND function is then used to draw a Polyline of zero width through the four corner points stored in variables PT2, PT6, PT5 and PT7. It is then used again to draw the line dividing the primary row from the first secondary row.

A REPEAT loop is then started that will repeat for one less than the number of rows. This redefines the list in variable PT8 to represent a new point that is the right distance and direction from the old PT8 point to start the next divider line. The next line of code draws the divider line and the loop will restart if necessary.

Variable CTR2 is then initialized to one less than the number of column widths there are listed in variable CL2. Another REPEAT loop is started that will run once for each column width. This starts by redefining PT2 to a point that is the CTR2'th column width as listed in variable CL2. CTR2 is then decremented by 1 so the next time through the loop the previous column width is obtained. By processing the list backwards, the column divider lines are drawn the the same order as they were specified since the CONS function that created the list always adds new elements to the front of the list, effectively creating it backwards.

The column divider line is then drawn from PT2 for the height of the table and in the right direction. The loop will then restart if necessary.

Once all the column divider lines have been drawn, the UNDO command is run to terminate the Undo group. The CMDECHO and BLIPMODE Setvars are restored to their previous values and the PRINC function is used to suppress the new value of BLIPMODE from being printed to the command line.
 

©1996-2001 ZOTO Technologies