Another useful aspect to programs such as AutoLISP is their ability to perform repetitive tasks. For example, suppose you want to be able to record a series of keyboard entries as a macro. One way to do this would be to use a series of Getstring functions as in the following :
(Setq str1 (getstring "\nEnter macro: ")) (Setq str2 (getstring "\nEnter macro: ")) (Setq str3 (getstring "\nEnter macro: ")) (Setq str4 (getstring "\nEnter macro: "))
Each of the str variables would then be combined to form a variable storing the keystrokes. Unfortunately, this method is inflexible. It requires that the user input a fixed number of entries, no more and no less. Also, this method would use memory storing each keyboard entry as a single variable.
It would be better if you had some facility to continually read keyboard input regardless of how few or how many different keyboard entries are supplied. The While function can be used to repeat a prompt and obtain data from the user until some test condition is met.
Here is the coding for our Macro Recorder :
(defun C:MACRO (/ str1 macro macname) (setq macro '(command)) ;start list with command (setq macname (getstring "\nEnter name of macro: ")) ;get name of macro (while (/= str1 "/") ;do while str1 not equal to / (setq str1 (getstring "\nEnter macro or / to exit: " )) ;get keystrokes (if (= str1 "/") (princ "\nEnd of macro ") ;if / then print message (Setq macro (append macro (list str1))) ;else append keystrokes to list ) ;end if macro list );end while (eval (list 'defun (read macname) '() macro)) ;create function (princ) );end macro (princ)
Now we will use the macro program to create a keyboard macro that changes the last object drawn to layer 3. Do the following :
- Draw a diagonal line from the lower left corner of the drawing area to the upper right corner.
- Load the Macro.lsp file.
- Enter Macro at the command prompt.
At the following prompt:
Enter name of macro:
Enter the word "CHLA".
At the prompt:
Enter macro or / to exit:
Enter the word "CHANGE"
The Enter macro prompt appears again. Enter the following series of words at each Enter macro prompt:
Enter macro or / to exit: L Enter macro or / to exit: press return Enter macro or / to exit: P Enter macro or / to exit: LA Enter macro or / to exit: 3 Enter macro or / to exit: press return Enter macro or / to exit: press return Enter macro or / to exit: /
This is where the
while function takes action. As you enter each
response to the Enter macro prompt,
while tests to see if you entered a
forward slash. If not, it evaluates the expressions included as its arguments. Once you
enter the backslash,
while stops its repetition. You get the prompt :
End of macro
The input you gave to the Enter macro prompt is exactly what you would enter if you had used the change command normally. Now run your macro by entering :
The line you drew should change to layer 3.
When Macro starts, it first defines two variables def and macro.
(setq def "defun ") (setq macro '(command))
Def is a string variable that is used later to define the macro. Macro is the beginning of a list variable which is used to store the keystrokes of the macro. The next line prompts the user to enter a name for the macro.
(setq macname (getstring "\nEnter name of macro: "))
The entered name is then stored with the variable macname.
Finally, we come to the
(while (/= str1 "/")
while expression is broken into several lines. The first line
contains the actual while function along with the test expression. In this case, the test compares the variable str1 with the string
"/" to see if they are not equal. So long as str1 is not equal
while will execute the arguments that follow the test.
The next four lines are the expressions to be evaluated. The first of
these lines prompts the user to enter the text that compose the macro.
(setq str1 (getstring "\nEnter macro or / to exit: " ))
When the user enters a value at this prompt, it is assigned to the variable str1.
The next line uses an if function to test if str1 is equal to "/".
(if (= str1 "/")
If the test results in T, the next line prints the string :
End of macro (princ "\nEnd of macro ")
This expression prints the prompt End of macro to the prompt line. If the test results in nil, the following line appends the value of str1 to the existing list macro.
(Setq macro (append macro (list str1)))
append function takes one list and appends its contents to the
end of another list. In this case, whatever is entered at the Enter macro
prompt is appended to the variable macro. Each time a new value is entered
at the Enter macro prompt, it is appended to the variable macro creating a
list of keyboard entries to be saved.
The next two lines close the if and while expressions.
);end if );end while
The last line combines all the elements of the program into an expression that, when evaluated, creates a new macro program.
(eval (list (read def) (read macname) '() macro))
The read function used in this expression is a special function that converts a string value into a symbol. If a string argument to read contains spaces, read will convert the first part of the string and ignore everything after the space.