Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
George Omura. Lisp programing tutorial for AutoCAD customization / 620.0.The ABC's of AutoLISP - Omura, George.pdf
Скачиваний:
140
Добавлен:
02.05.2014
Размер:
1.55 Mб
Скачать

The ABC’s of AutoLISP by George Omura

Searching for Strings

The program Chtxt shown in figure 7.1 is a simple line editor. It uses AutoLISPs string handling functions to locate a specific string, then it replaces that string with another one specified by the user.

Open a file called chtxt.lsp and copy the program shown in figure 7.1 into the file. Save and close this file and open a new AutoCAD file called Chapt7.

;function to find text string from text entity

-------------------------------

(defun gettxt ()

 

(setvar "osmode" 64)

;set osnap to insert

(setq pt1 (getpoint "\nPick text to edit: "))

;get point on text

(Setvar "osmode" 0)

;set osnap back to zero

(setq oldobj (entget (ssname (ssget pt1) 0) ))

;get entity zero from prop.

(setq txtstr (assoc 1 oldobj))

;get list containing string

(cdr txtstr)

;extract string from prop.

)

 

;function to update text string of text entity-------------------------------

 

(defun revtxt ()

 

(setq newtxt (cons 1 newtxt))

;create replacement propty.

(entmod (subst newtxt txtstr oldobj))

;update database

)

 

;program to edit single line of text-----------------------------------------

 

(defun C:CHTXT (/ count oldstr newstr osleng otleng oldt old1

old2 newtxt pt1 oldobj txtstr oldtxt)

 

(setq count 0)

;setup counter to zero

(setq oldtxt (gettxt))

;get old string

from text

(setq otleng (strlen oldtxt))

;find length of

old string

(setq oldstr (getstring T "\nEnter old string "))

;get string to change

(Setq newstr (getstring T "\nEnter new string "))

;get replacement string

(setq osleng (strlen oldstr))

;find length of

substring-

;while string to replace is not found, do...

to be replaced

 

(while (and (/= oldstr oldt)(<= count otleng))

 

 

(setq count (1+ count))

;add 1 to counter

(setq oldt (substr oldtxt count osleng))

;get substring to compare

);end WHILE

;if counting stops before end of old string is reached...

(if (<= count otleng) (progn

(setq old1 (substr oldtxt 1 (1- count))) ;get 1st half of old string (setq old2 (substr oldtxt (+ count osleng) otleng));get 2nd half

(setq newtxt (strcat old1 newstr old2))

;combine to make new string

(revtxt)

;update drawing

)

 

(princ "\nNo matching string found.")

;else print message

);end IF

 

(PRINC)

 

);END C:EDTXT

 

 

 

 

 

Figure 7.1: The Chtxt.lsp file

139

Copyright © 2001 George Omura,,World rights reserved

The ABC’s of AutoLISP by George Omura

Load the Chtxt.lsp file and do the following steps:

1. Use the Dtext command and write the following line of text:

For want of a battle, the kingdom was lost.

2.Enter Chtxt

3.At the prompt:

Pick text to edit:

pick the text you just entered. Note that the osnap cursor appears.

4. At the next prompt:

Enter old string:

enter the word battle in lower case letters.

5. At the next prompt:

Enter new string:

enter the word nail.

The text changes to read:

For want of a nail, the kingdom was lost.

In the C:CHTXT program, you are able to change a group of letters in a line of text without having to enter entire line over again. Also, you don't have to go through a series of unneeded prompts as you do with the change command. The following describes what C:CHTXT goes through to accomplish this.

The C:CHTXT program starts out with a user defined function called gettxt.

(defun C:EDTXT (/ count oldstr newstr osleng otleng oldt old1 old2 newtxt pt1 oldobj txtstr oldtxt)

(setq count 0)

(setq oldtxt (gettxt))

Gettxt prompts you to select the text to be edited. It then extracts from the drawing database the text string associated with that text. The extracted text is assigned to the symbol oldtxt. We will look at this extraction process in Chapter--- but for now, think of the gettxt function as a function for getting text.

140

Copyright © 2001 George Omura,,World rights reserved

The ABC’s of AutoLISP by George Omura

In the next line of the Chtxt program, we see a new function strlen:

(setq otleng (strlen oldtxt))

Strlen finds the number of characters in a string.

The syntax for strlen is:

(strlen [string or string variable])

Strlen returns an integer value representing the number of characters found in its arguments. Blank spaces are counted as characters. In the above expression, the value found by strlen is assigned to the variable otleng.

The next two expressions obtain from the user the old portion of the text to be replace and the replacement text.

(setq oldstr (getstring T "\nEnter old string "))

(Setq newstr (getstring T "\nEnter new string "))

These two strings are saved as oldstr and newstr. Note that the T argument is used with getstring to allow the user to use spaces in the string.

The next set of expressions do the work of the program. First, The number of characters of the string to be replaced, oldstr, is found by using the strlen function:

(setq osleng (strlen oldstr))

This value is stored with a variable called osleng. Osleng will be used to find exactly where in the line of text the old string occurs in the line of text being edited (see figure 7.2).

Figure 7.2: Using the strlen function

The following while function uses osleng\ to find the exact location of oldstr within oldtxt.

(while (and (/= oldstr oldt)(<= count otleng))

(setq count (1+ count))

(setq oldt (substr oldtxt count osleng))

);end WHILE

141

Copyright © 2001 George Omura,,World rights reserved

The ABC’s of AutoLISP by George Omura

The while expression tests for two conditions. The first test is to see of the current string being read matches the string entered at the "String to be changed" prompt. The second test checks to see if the end of the text line has been reached. The and logical operator is used to make sure that both test conditions are met before it continues evaluating its other expressions.

We see a new function substr in this group of expressions:

(Setq oldt (substr oldtxt count osleng))

Substr extracts a sequence of characters from a string. Its syntax is:

(substr

[string or string variable]

[beginning of substring][end of substring]

)

The first argument to substr is the string within which a substring is to be extracted. By substring, we mean a group of characters that are contained within the main string. The substring can be any contiguous sequence of characters within the main string including the entire string itself. The second argument is the beginning location for the substring. This can be an integer from 1 to the total number of characters in the main string. The third argument is the ending location of the substring. This value is an integer greater than or equal to the value for the beginning of the substring and it determines the ending location of the substring (see figure 7.3).

Figure 7.3: Using the substr function

142

Copyright © 2001 George Omura,,World rights reserved

The ABC’s of AutoLISP by George Omura

The while expression extracts a group of characters from oldtxt starting at the beginning. It stores this substring in the variable oldt. Oldt is then compared with oldstr to see if they match. If the don't match, then while advances to the next group of characters in oldtxt and compares this new group to oldstr. This goes on until a match is found or the end of oldtxt is reached (See figure 7.4).

Figure 7.4: Using the while expression to find a matching string.

143

Copyright © 2001 George Omura,,World rights reserved

The ABC’s of AutoLISP by George Omura

String data types are case sensitive, This means that if you had entered "BATTLE" instead of "battle" at the string to change prompt, you would have gotten the message:

No matching string found.

The string "BATTLE" is not equal to "battle" so as edtxt tries to find a string that matches "BATTLE", it never finds it.

When the while expression is done, the next group of expressions takes the old text line apart and replaces the old string with the new. First the if function is used to test whether the oldstring was indeed found.

(if (<= count otleng)

The if expression checks to see if the variable count is equal to or less than the length of the old text line. If count is less than otleng, then the following set of expressions are evaluated:

(progn

(setq old1 (substr oldtxt 1 (1- count)))

(setq old2 (substr oldtxt (+ count osleng) otleng)) (setq newtxt (strcat old1 newstr old2))

(revtxt)

)

The progn function allows the group of expressions that follow to appear as one expression to the if function. The first expression of this group:

(setq old1 (substr oldtxt 1 (1- count)))

separates out the first part of the old text line just before the old string. This is done using the substr function and the count variable to find the beginning of the old string (see figure 7.5).

Figure 7.5: Finding the string before oldstr

144

Copyright © 2001 George Omura,,World rights reserved

The ABC’s of AutoLISP by George Omura

The next expression:

(setq old2 (substr oldtxt (+ count osleng) otleng))

separates out the last part of the old text line starting just after the old string. Again this is done using the substr function and the count variable. This time, count is added to osleng to find the location of the end of the old string. Otleng is used for the substring length. Even though its value is greater than the length of the substring w wan, AutoLISP will read the substring to the end of Oldtxt (see figure 7.6).

Figure 7.6: Finding the string after oldstr

Finally, the expression:

(setq newtxt (strcat old1 newstr old2))

combines the first and last part of the old text line with the new string to form the replacement text line (see figure 7.7).

Figure 7.7: Combining the old string with the new

The last expression in this group:

145

Copyright © 2001 George Omura,,World rights reserved

The ABC’s of AutoLISP by George Omura

(revtxt)

is a user defined function that does the work of replacing the old text with the new.

(defun revtxt ()

(setq newtxt (cons 1 newtxt))

(entmod (subst newtxt txtstr oldobj))

)

In the event that count is greater than otleng, the following expression is evaluated:

(princ "\nNo matching string found.")

);end IF

This expression prints the message:

No matching string found.

to the prompt line.

The very last expression of the program:

(PRINC)

);END C:EDTXT

seems pretty useless at first glance. Princ without any arguments prints a blank to the prompt line. If this expression were not here, however, AutoLISP would display the value of the last expression evaluated. Remember that AutoLISP constantly cycles through the read-evaluate-print loop. The generally, the value of the last expression evaluated is printed to the prompt line. While this doesn't affect the workings of the program, it may prove to be an annoyance to the user or it may confuse someone not familiar with the program. Since princ will print a blank at the prompt line when no arguments are supplied, it is often used without arguments at the end of a program simply to keep the appearance of the program clean. If you like, try deleting the Princ expression from the program and reload and run the program again. You will a value will appear in the prompt line when C:EDTXT finishes running.

How to Convert Numbers to String and Back

There are times when it is necessary to convert a string value to a number or vice versa. Suppose, for example, that you want to be able to control the spacing of numbers generated by the program in chapter 5. You may recall that this program creates a sequence of numbers equally spaced. The user is able to determine the beginning and ending numbers and the location of the beginning number but cannot determine the distance between numbers. You can use the rtos function to help obtain a distance value and include it with the program. Figure 7.8 shows the C:SEQ program from chapter 5 modified to accept distance input.

146

Copyright © 2001 George Omura,,World rights reserved