Author Topic: Help with code to extract a string from text.  (Read 7605 times)

0 Members and 1 Guest are viewing this topic.

bchapman

  • Guest
Re: Help with code to extract a string from text.
« Reply #15 on: February 10, 2013, 09:22:40 PM »
Thanks CAB!

CAB... if you have time can you please help me understand what the repercussions are of not handling this in this case?

It is bad practice to allow your lisp to crash. Better practice to plan ahead and make a soft landing.  8-)
In a more complicated lisp you may have changed the ACAD environment and a crash will leave the DWG setting in an unexpected state.
This can be very aggravating to the end user. I'm not saying that in these code snippets that you impalement a full error trp but when you can avoid the crash with line or two of extra code that it is good form to do so.
I'm sure I've been guilty of the same faux pas in my past but do make an effort to avoid it today.  :-)

Reu

  • Guest
Re: Help with code to extract a string from text.
« Reply #16 on: February 11, 2013, 10:29:55 AM »
Try this one on for size.
Code - Auto/Visual Lisp: [Select]
  1. ;;; Function (C:MCHAR) ;
  2. ;;; Description: This program is to get a number of characters from the end ;
  3. ;;; of a text string and place them at the beginning of a 2nd string. ;
  4. (defun c:mchar (/ #chrs ss1 ss2 txt1 txt2 str entlst)
  5.  
  6.   (and
  7.     (princ "\nAppend characters from 1st text to the 2nd text")
  8.     (setq #chrs (getint "\nHow many characters do you want to move?"))
  9.     (princ "\nSelect the 1st Text to get chars.")
  10.     (setq ss1 (ssget "_:S" '((0 . "TEXT"))))
  11.     (setq txt1 (cdr (assoc 1 (entget (ssname ss1 0)))))
  12.     (princ "\nSelect the Text to add chars to.")
  13.     (setq ss2 (ssget "_:S" '((0 . "TEXT"))))
  14.     (setq entlst (entget (ssname ss2 0)))
  15.     (setq str (substr txt1 (1+ (- (strlen txt1) #chrs))))
  16.  
  17.     (entmod ; update the following ent list
  18.       (subst ; make some changes to the list
  19.         (cons 1 (strcat (cdr (assoc 1 entlst)) str)) ; new string + dxf 1
  20.         (assoc 1 entlst) ; old string with dxf code
  21.         entlst ; original ent list
  22.       )
  23.     )
  24.   )
  25.   (princ "\nType MCHAR to invoke.")
  26.   (princ)
  27. )

Works great!

Two problems. . .
1) It leaves the text in the 1st string. Need to delete the text from that string, while (or after) adding it to the 2nd string.
2) It adds the text at the end of the 2nd string, not the beginning.

Also I did not mention it in my code description but this also needs to add a space between the last character of the string being moved and the first character of the 2nd string.
« Last Edit: February 11, 2013, 10:43:38 AM by Reu »

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: Help with code to extract a string from text.
« Reply #17 on: February 11, 2013, 10:50:46 AM »
See if you can modify the code to do what you want.
It will be good practice exercise for you.  8-)
« Last Edit: February 11, 2013, 10:59:52 AM by CAB »
I've reached the age where the happy hour is a nap. ()
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

Reu

  • Guest
Re: Help with code to extract a string from text.
« Reply #18 on: February 11, 2013, 10:52:23 AM »
See if you can modify the code to do what you want.
It will be good practice exercise for you.  8-)

Right you are, as I intend to teacher  :lol:

Learning is fun!
« Last Edit: February 11, 2013, 11:00:03 AM by CAB »

Lee Mac

  • Seagull
  • Posts: 12902
  • London, England
Re: Help with code to extract a string from text.
« Reply #19 on: February 11, 2013, 10:55:44 AM »
Here is another selection method to consider:

Code: [Select]
(defun c:mchar ( / e1 e2 no s1 s2 sl )
    (if
        (and
            (setq e1 (LM:SelectifObject "\nSelect 1st Text: " "TEXT"))
            (setq e2 (LM:SelectifObject "\nSelect 2nd Text: " "TEXT"))
            (progn
                (initget 6)
                (setq no (getint "\nNumber of Characters: "))
            )
        )
        (progn
            (setq e1 (entget e1)
                  e2 (entget e2)
                  s1 (cdr (assoc 1 e1))
                  s2 (cdr (assoc 1 e2))
            )
            (if (< no (setq sl (strlen s1)))
                (progn
                    (entmod (subst (cons 1 (substr s1 1 (- sl no))) (assoc 1 e1) e1))
                    (entmod (subst (cons 1 (strcat (substr s1 (- sl no -1)) " " s2)) (assoc 1 e2) e2))
                )
                (princ "\nText is shorter than number of characters.")
            )
        )
    )
    (princ)
)

;; Select if Object  -  Lee Mac
;; Continuously prompts the user for a selection of a specific object

(defun LM:SelectifObject ( msg obj / ent )
    (while
        (progn (setvar 'errno 0) (setq ent (car (entsel msg)))
            (cond
                (   (= 7 (getvar 'errno))
                    (princ "\nMissed, try again.")
                )
                (   (= 'ename (type ent))
                    (if (/= obj (cdr (assoc 0 (entget ent))))
                        (princ "\nInvalid Object Selected.")
                    )
                )
            )
        )
    )
    ent
)

Reu

  • Guest
Re: Help with code to extract a string from text.
« Reply #20 on: February 11, 2013, 11:05:11 AM »
Here is another selection method to consider:

Code: [Select]
(defun c:mchar ( / e1 e2 no s1 s2 sl )
    (if
        (and
            (setq e1 (LM:SelectifObject "\nSelect 1st Text: " "TEXT"))
            (setq e2 (LM:SelectifObject "\nSelect 2nd Text: " "TEXT"))
            (progn
                (initget 6)
                (setq no (getint "\nNumber of Characters: "))
            )
        )
        (progn
            (setq e1 (entget e1)
                  e2 (entget e2)
                  s1 (cdr (assoc 1 e1))
                  s2 (cdr (assoc 1 e2))
            )
            (if (< no (setq sl (strlen s1)))
                (progn
                    (entmod (subst (cons 1 (substr s1 1 (- sl no))) (assoc 1 e1) e1))
                    (entmod (subst (cons 1 (strcat (substr s1 (- sl no -1)) " " s2)) (assoc 1 e2) e2))
                )
                (princ "\nText is shorter than number of characters.")
            )
        )
    )
    (princ)
)

;; Select if Object  -  Lee Mac
;; Continuously prompts the user for a selection of a specific object

(defun LM:SelectifObject ( msg obj / ent )
    (while
        (progn (setvar 'errno 0) (setq ent (car (entsel msg)))
            (cond
                (   (= 7 (getvar 'errno))
                    (princ "\nMissed, try again.")
                )
                (   (= 'ename (type ent))
                    (if (/= obj (cdr (assoc 0 (entget ent))))
                        (princ "\nInvalid Object Selected.")
                    )
                )
            )
        )
    )
    ent
)

Hey that works perfect Lee!

Here I am trying to learn to doggy-paddle and Lee throws me into the middle of the Atlantic (Code) ocean.  :ugly:

Shoot for the stars, that way if you miss you'll at least make the moon, eh?

Lee Mac

  • Seagull
  • Posts: 12902
  • London, England
Re: Help with code to extract a string from text.
« Reply #21 on: February 11, 2013, 11:07:51 AM »
Here I am trying to learn to doggy-paddle and Lee throws me into the middle of the Atlantic (Code) ocean.  :ugly:

Sorry - I didn't mean to overwhelm you  :oops:

Reu

  • Guest
Re: Help with code to extract a string from text.
« Reply #22 on: February 11, 2013, 11:15:35 AM »
Here I am trying to learn to doggy-paddle and Lee throws me into the middle of the Atlantic (Code) ocean.  :ugly:

Sorry - I didn't mean to overwhelm you  :oops:

Did not mean it in a bad way Lee just trying to be funny. I have nothing but the highest respect for your programming abilities.

Genius must not hold back because it opens the eyes of the ignorant to see their need of knowledge, wisdom, and understanding.

It will do one of two things:
1) Spur them to diligent study.
2) Cause them to give up in despair.

Which of the two is determined by the constitution of the unlearned person, do they truly want to learn.

Endurance

Lee Mac

  • Seagull
  • Posts: 12902
  • London, England
Re: Help with code to extract a string from text.
« Reply #23 on: February 11, 2013, 11:35:43 AM »
Thank you Reuben  :-)
I hardly consider myself a genius (far from it), but I fully agree with your sentiments - we all stand on the shoulders of giants  :-)

Reu

  • Guest
Re: Help with code to extract a string from text.
« Reply #24 on: February 11, 2013, 12:32:24 PM »
Thank you Reuben  :-)
I hardly consider myself a genius (far from it), but I fully agree with your sentiments - we all stand on the shoulders of giants  :-)

OK Lee, here is my attempt to add comments to your program, they are incomplete but I hope you can see that my understanding of AutoLISP is growing. . .and that I have a long way to go. I have included questions within the comments on things that I do not understand (they should all be in parentheses of their own with question marks within the comments).

Thanks again for your help,
     Reuben Shilling

Code: [Select]
(defun c:mchar ( / e1 e2 no s1 s2 sl )
    (if
        (and
            (setq e1 (LM:SelectifObject "\nSelect 1st Text: " "TEXT")) ; Set variable "e1" to 1st text, setting variable "msg" to a 'space' character and variable "obj" to 'TEXT'.
            (setq e2 (LM:SelectifObject "\nSelect 2nd Text: " "TEXT")) ; Set variable "e2" to 2nd text, setting variable "msg" to a 'space' character and variable "obj" to 'TEXT'.
            (progn
                (initget 6) ; Zero and negative values not allowed
                (setq no (getint "\nNumber of Characters: ")) ; Set variable "no" to number of characters to be removed
            ) ;_end progn
        ) ;_end and
        (progn
            (setq e1 (entget e1) ; Set variable "e1" to the entity properties of the user defined object from the previous value of "e1" variable.
                  e2 (entget e2) ; Set variable "e2" to the entity properties of the user defined object from the previous value of "e2" variable.
                  s1 (cdr (assoc 1 e1)) ; Set variable "s1" to the string of variable "e1". (Unsure why the "cdr" function is used here?)
                  s2 (cdr (assoc 1 e2)) ; Set variable "s2" to the string of variable "e2". (Unsure why the "cdr" function is used here?)
            ) ;_end setq
            (if (< no (setq sl (strlen s1))) ; If the user specified number of characters to be moved is less than then length of the string stored under variable "s1" (Unsure how "setq sl" fits here?).
                (progn ;Perform these actions. . .
                    (entmod (subst (cons 1 (substr s1 1 (- sl no))) (assoc 1 e1) e1)) ; Modify the . . .?
                    (entmod (subst (cons 1 (strcat (substr s1 (- sl no -1)) " " s2)) (assoc 1 e2) e2)) ; Modify the . . .?
                ) ;_end progn
                (princ "\nText is shorter than number of characters.") ; Else print this message.
            ) ;_end if
        ) ;_end progn
    ) ;_end if
    (princ) ;_exit quietly
) ;_end defun

;; Select if Object  -  Lee Mac
;; Continuously prompts the user for a selection of a specific object

(defun LM:SelectifObject ( msg obj / ent )
    (while
        (progn (setvar 'errno 0) (setq ent (car (entsel msg))) ; Ensure that the variable for error recognition is set to 0, then set variable "ent" to the first element of the list returned by entsel. (I am unsure as to the use of msg?)
            (cond
                (   (= 7 (getvar 'errno)) ; If errno = 7  (Why the multiple spacings between parentheses?)
                    (princ "\nMissed, try again.") ; Print this message
                ) ;_end ?
                (   (= 'ename (type ent)) ; Check the variable "ent" to see if it is an entity name.  (Why the multiple spacings between parentheses?)
                    (if (/= obj (cdr (assoc 0 (entget ent)))) ; If variable "obj" is not equal to the DXF text string specified of variable "ent"
                        (princ "\nInvalid Object Selected.") ; Print this message.
                    ) ;_end if
                ) ;_end ?
            ) ;_end cond
        ) ;_end progn
    ) ;_end while
    ent ;; What is this here for?
) ;_end defun

Reu

  • Guest
Re: Help with code to extract a string from text.
« Reply #25 on: February 11, 2013, 01:26:03 PM »
See if you can modify the code to do what you want.
It will be good practice exercise for you.  8-)

Question:

In this line of code:
Code: [Select]
(setq str (substr txt1 (1+ (- (strlen txt1) #chrs))))what is the reason for the 1+?

Also a further question on 'entmod':
This variable is basically used to access and modify the 'properties' of an entity?
« Last Edit: February 11, 2013, 01:38:52 PM by Reu »

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: Help with code to extract a string from text.
« Reply #26 on: February 11, 2013, 02:34:47 PM »
The 1+ and 1- are functions that add or subtract one. It is such a common operation that they made a special function for that.

Yes, the entmod just modifies the entity given a valid entity list. Note that you sometimes need entupd or a regen to show the updated object.

Your code posted with comment to my code were correct. You just need to entmod the first text object as well.

I've reached the age where the happy hour is a nap. ()
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

Reu

  • Guest
Re: Help with code to extract a string from text.
« Reply #27 on: February 11, 2013, 05:15:21 PM »
The 1+ and 1- are functions that add or subtract one. It is such a common operation that they made a special function for that.

Yes, the entmod just modifies the entity given a valid entity list. Note that you sometimes need entupd or a regen to show the updated object.

Your code posted with comment to my code were correct. You just need to entmod the first text object as well.

Do I pass now?

Code: [Select]
;;; Function (C:MCHAR) ;
;;; Description: This program is to remove a number of characters from the end ;
;;; of a text string and place them at the beginning of a 2nd string. ;
(defun c:mchar (/ #chrs ss1 ss2 entlst1 entlst2 txt1 txt2 str)

  (and
    (princ "\nAppend characters from 1st text to the 2nd text.")
; Print message to tell user what the program does.
    (setq #chrs (getint "\nHow many characters do you want to move? "))
; Set variable "#chars" to user defined number of characters to move.
    (princ "\nSelect the 1st Text to get chars.")
; Print message to tell user what to do.
    (setq ss1 (ssget "_:S" '((0 . "TEXT"))))
; Set variable "ss1" to the user defined text object to move characters from.
    (setq entlst1 (entget (ssname ss1 0)))
; Set variable "entlst1" to the association list of the user defined text to move characters from.
    (setq txt1 (cdr (assoc 1 (entget (ssname ss1 0)))))
; Set variable "txt1" to the text string of the user defined text to move characters from.
    (princ "\nSelect the Text to add chars to.")
; Print message to tell the user what to do.
    (setq ss2 (ssget "_:S" '((0 . "TEXT"))))
; Set variable "ss2" to the user defined text object to move characters to.
    (setq entlst2 (entget (ssname ss2 0)))
; Set variable "entlst2" to the association list of the user defined text to move the characters to.
    (setq txt2 (cdr (assoc 1 (entget (ssname ss2 0)))))
; Set variable "txt2" to the text string of the user defined text to move characters from.
    (setq str (substr txt1 (1+ (- (strlen txt1) #chrs))))
; Set variable "str" to the text string to be moved from 1st text to 2nd text.

    (entmod ; update the following entity list
      (subst ; make some changes to the list "entlst2"
(cons 1 (strcat str " " (cdr (assoc 1 entlst2))))
; new string + 'space character' + dxf 1
(assoc 1 entlst2) ; old string with DXF code "1"
entlst2 ; original entity association list
      ) ;_end subst
    ) ;_end entmod
    (entmod
      (subst ; make some changes to the list "txt1"
(cons 1 (substr txt1 1 (- (strlen txt1) (+ 3 #chars))))
; "txt1" - ("#chars" + 3)
(assoc 1 entlst1) ; old string with DXF code "1"
entlst1 ; original entity association list
      ) ;_end subst
    ) ;_end entmod
  ) ;_end and
  (princ "\nType MCHAR to invoke.")
  (princ)
) ;_end defun

 :-o

Lee Mac

  • Seagull
  • Posts: 12902
  • London, England
Re: Help with code to extract a string from text.
« Reply #28 on: February 11, 2013, 07:02:25 PM »
OK Lee, here is my attempt to add comments to your program, they are incomplete but I hope you can see that my understanding of AutoLISP is growing. . .and that I have a long way to go. I have included questions within the comments on things that I do not understand (they should all be in parentheses of their own with question marks within the comments).

I have tried my best to fully explain the program line-by-line as comprehensibly as possible.

If there are functions that you do not understand or if you are unclear as to why a function has been used, I would strongly recommend that you first refer to the AutoLISP Help Documentation accessible from the Visual LISP IDE, as this documentation will explain the behaviour of the function, its required & optional arguments and its expected returns. I have written a short tutorial explaining how to access this documentation here.

Typos may lurk herein

Code - Auto/Visual Lisp: [Select]
  1. (defun c:mchar ( / e1 e2 no s1 s2 sl ) ;; Define function, declare local variables
  2.    
  3.     (if ;; If the following expression returns a non-nil value
  4.        
  5.         (and ;; All of the following expressions must return a non-nil value for AND to return T
  6.            
  7.             (setq e1 ;; Assign the return of the LM:SELECTIFOBJECT function to the local variable 'e1'
  8.  
  9.                 (LM:SelectifObject "\nSelect 1st Text: " "TEXT")
  10.  
  11.                 ;; Call the LM:SELECTIFOBJECT function with the two required arguments
  12.                 ;; Here, the 'msg' parameter is passed the string value "\nSelect 1st Text: "
  13.                 ;; and the 'obj' parameter is passed the string value "TEXT"
  14.                 ;;
  15.                 ;; At this point we needn't know how this function operates, only that it requires
  16.                 ;; a prompt message argument and an entity type string argument, and that it returns
  17.                 ;; the entity name of a valid selected entity, or NIL if the user fails to select a
  18.                 ;; valid entity.
  19.                 ;;
  20.                 ;; View the LM:SELECTIFOBJECT function as just another AutoLISP function; imagine
  21.                 ;; that you don't have access to the function definition. Consider that you don't have access
  22.                 ;; to the inner workings of the SETQ function, however, you know that SETQ requires
  23.                 ;; a set of symbol and value pairs, and will return the value of the last pair.
  24.                
  25.             ) ;; end SETQ
  26.  
  27.             (setq e2 ;; Assign the return of the LM:SELECTIFOBJECT function to the local variable 'e2'
  28.  
  29.                 (LM:SelectifObject "\nSelect 2nd Text: " "TEXT")
  30.  
  31.                 ;; Call the LM:SELECTIFOBJECT function with the two required arguments
  32.                 ;; Now, the 'msg' parameter is passed the string value "\nSelect 2nd Text: "
  33.                 ;; and the 'obj' parameter is again passed the string value "TEXT"
  34.  
  35.             ) ;; end SETQ
  36.            
  37.             (progn ;; Evaluate the following expressions and return the result of the last expression evaluated
  38.                
  39.                 (initget 6) ;; Reject zero & negative values (bits 1 & 2)
  40.                
  41.                 (setq no ;; Assign the return of the GETINT function to the local variable 'no'
  42.  
  43.                     (getint "\nNumber of Characters: ")
  44.  
  45.                     ;; Prompt the user for a number of characters to remove.
  46.                     ;; Since this is the first user-input function to follow the INITGET expression
  47.                     ;; the user input will be restricted to positive non-zero integers.
  48.  
  49.                 ) ;; end SETQ
  50.  
  51.                 ;; The SETQ expression is the last expression evaluated within the PROGN expression
  52.                 ;; and hence the result of this expression is returned by the PROGN expression and
  53.                 ;; evaluated by the AND function.
  54.                
  55.             ) ;; end PROGN
  56.            
  57.         ) ;; end AND
  58.        
  59.         (progn ;; Evaluate the following expressions and return the result of the last expression evaluated
  60.            
  61.             (setq e1 ;; Assign the return of the ENTGET function to the local variable 'e1' (overwriting its previous value)
  62.                    
  63.                 (entget e1)
  64.                 ;; Retrieve the list of DXF data for the entity name assigned to the local variable 'e1'
  65.                 ;; We know that variable 'e1' will definitely hold an entity name value, since
  66.                 ;; otherwise the AND expression would not be satisfied and the 'then' expression
  67.                 ;; for the IF function would not be evaluated.
  68.                
  69.                   e2 ;; Assign the return of the ENTGET function to the local variable 'e2' (overwriting its previous value)
  70.                      ;; Note that the SETQ function can be passed multiple symbol/value pairs, however only the value of
  71.                      ;; the last pair will be returned, hence it was necessary to separate the SETQ statements within
  72.                      ;; the AND expression to ensure every pair held a non-nil value.
  73.  
  74.                 (entget e2)
  75.  
  76.                 ;; Retrieve the list of DXF data for the entity name assigned to the local variable 'e2'
  77.                
  78.                   s1 ;; Assign the return of the CDR function to the local variable 's1'
  79.  
  80.                 (cdr ;; Return the second element of the DXF dotted pair (see the documentation on the CDR function)
  81.  
  82.                     (assoc 1 e1)
  83.                     ;; Retrieve the dotted pair (or list) with first item equal to 1 from the DXF data list
  84.                     ;; assigned to local variable e1 (i.e. the text content of the first text entity).
  85.                     ;; Since DXF Group code 1 holds a string value, the return will be a dotted pair, e.g.:
  86.                     ;; (1 . "String")
  87.  
  88.                 ) ;; end CDR
  89.  
  90.                   s2 ;; Assign the return of the CDR function to the local variable 's2'
  91.                    
  92.                 (cdr ;; Return the second element of the DXF dotted pair (see the documentation on the CDR function)
  93.                    
  94.                     (assoc 1 e2)
  95.                     ;; Retrieve the dotted pair (or list) with first item equal to 1 from the DXF data list
  96.                     ;; assigned to local variable e2 (i.e. the text content of the second text entity).
  97.                    
  98.                 ) ;; end CDR
  99.                
  100.             ) ;; end SETQ
  101.            
  102.             (if ;; If the following expression returns a non-nil value
  103.                
  104.                 (<  ;; Returns T if each argument is numerically less than the argument to its right
  105.                    
  106.                     no ;; Number of characters as specified by the user
  107.                    
  108.                     (setq sl ;; Assign the return of the STRLEN function to the local variable 'sl'
  109.                            
  110.                         (strlen s1) ;; Retrieve the number of characters of the text content of the first text entity
  111.                        
  112.                     ) ;; end SETQ
  113.  
  114.                     ;; Here we are testing whether the number of characters to be moved
  115.                     ;; is less than the string length of the string held by the first text entity
  116.                     ;; The string length is assigned to local variable 'sl' as it will be used later
  117.                     ;; the program, hence improving efficiency.
  118.                    
  119.                 ) ;; end <
  120.                
  121.                 (progn ;; Evaluate the following expressions and return the result of the last expression evaluated
  122.                    
  123.                     (entmod ;; Modify the DXF data in the drawing database for the following DXF data list
  124.  
  125.                         (subst ;; Substitute the following for every occurrence of the second argument in the list supplied
  126.  
  127.                             (cons 1 ;; Construct a dotted pair with first element equal to 1
  128.  
  129.                                 (substr s1 1 (- sl no))
  130.                                 ;; Return a section of the string held by the 's1' variable (i.e. the content
  131.                                 ;; of the first text entity), beginning at character 1 (the first character)
  132.                                 ;; and spanning a number of characters equal to the string length minus the number
  133.                                 ;; of characters to be removed
  134.  
  135.                             ) ;; end CONS
  136.  
  137.                             (assoc 1 e1)
  138.                             ;; Retrieve the dotted pair to be replaced in the DXF data list
  139.                             ;; Note that this could alternatively be (cons 1 s1)
  140.  
  141.                             e1 ;; The DXF data list in which the dotted pair substitution is to be made
  142.                            
  143.                         ) ;; end SUBST
  144.                        
  145.                     ) ;; end ENTMOD
  146.                    
  147.                     (entmod ;; Modify the DXF data in the drawing database for the following DXF data list
  148.  
  149.                         (subst ;; Substitute the following for every occurrence of the second argument in the list supplied
  150.  
  151.                             (cons 1 ;; Construct a dotted pair with first element equal to 1
  152.  
  153.                                 (strcat ;; Concatenate the following strings
  154.  
  155.                                     (substr s1 (- sl no -1))
  156.                                     ;; Return a section of the string held by the 's1' variable (i.e. the content
  157.                                     ;; of the first text entity), beginning at the character whose number is
  158.                                     ;; given by the string length minus the number of characters to be removed
  159.                                     ;; minus minus 1 (i.e. add one), spanning the remaining characters in the
  160.                                     ;; string.
  161.                                    
  162.                                     " " ;; Include a space between the added characters and the existing content
  163.                                    
  164.                                     s2 ;; The existing text content of the second text entity
  165.                                    
  166.                                 ) ;; end STRCAT
  167.                                
  168.                             ) ;; end CONS
  169.  
  170.                             (assoc 1 e2)
  171.                             ;; Retrieve the dotted pair to be replaced in the DXF data list
  172.                             ;; Note that this could alternatively be (cons 1 s2)
  173.  
  174.                             e2 ;; The DXF data list in which the dotted pair substitution is to be made
  175.  
  176.                         ) ;; end SUBST
  177.                        
  178.                     ) ;; end ENTMOD
  179.                    
  180.                 ) ;; end PROGN
  181.                
  182.                 (princ "\nText is shorter than number of characters.") ;; Else notify the user of invalid input
  183.                
  184.             ) ;; end IF
  185.            
  186.         ) ;; end PROGN
  187.  
  188.         ;; Here we could notify the user that they either haven't selected one or more text entities
  189.         ;; or that they haven't specified a number of characters, however, they already know that...
  190.        
  191.     ) ;; end IF
  192.    
  193.     (princ) ;; Suppress the return of the last evaluated expression (in this case, the IF function)
  194.    
  195. ) ;; end DEFUN, function is defined
  196.  
  197. ;; Select if Object  -  Lee Mac
  198. ;; Continuously prompts the user for a selection of a specific object
  199.  
  200. (defun LM:SelectifObject ( msg obj / ent )
  201.     ;; Define function, declare required arguments and local variables
  202.     ;; In this case, the function requires two arguments, the values of
  203.     ;; which will be held by the parameters 'msg' & 'obj'
  204.    
  205.     (while ;; while the following returns a non-nil value
  206.        
  207.         (progn ;; Evaluate the following expressions and return the result of the last expression evaluated
  208.  
  209.             (setvar 'errno 0) ;; Reset the ERRNO System Variable to zero
  210.  
  211.             (setq ent ;; Assign the return of the CAR function to the local variable 'ent'
  212.  
  213.                 (car ;; Return the first item of the list returned by ENTSEL (or return nil)
  214.  
  215.                     (entsel msg)
  216.                     ;; Evaluate the ENTSEL function with the optional prompt argument
  217.                     ;; taking the value held by the 'msg' parameter supplied to the LM:SELECTIFOBJECT function
  218.  
  219.                 ) ;; end CAR
  220.  
  221.             ) ;; end SETQ
  222.            
  223.             (cond
  224.             ;; Evaluate the test expression for each condition and evaluate the expressions following
  225.             ;; the test expression for the first test expression returning a non-nil value
  226.                
  227.                 (    ;; Condition 1 - the parenthesis spacing is purely aesthetic
  228.  
  229.                      (= 7 (getvar 'errno))
  230.                      ;; Test whether the ERRNO System Variable equals 7
  231.                      ;; (i.e. a missed selection - the user clicked empty space)
  232.  
  233.                      (princ "\nMissed, try again.") ;; if ERRNO = 7, notify user has missed the selection
  234.                  
  235.                 ) ;; end Condition 1
  236.                
  237.                 (    ;; Condition 2
  238.  
  239.                      (= 'ename (type ent))
  240.                      ;; Test whether the local variable 'ent' points to a value of
  241.                      ;; ename type (entity name)
  242.  
  243.                      ;; Variable 'ent' has entity name value, so...
  244.                  
  245.                      (if ;; If the following expression returns a non-nil value
  246.                          
  247.                          (/= ;; Returns T if no two successive arguments are equal
  248.                              
  249.                              obj ;; The entity type string argument passed to the LM:SELECTIFOBJECT function
  250.                              
  251.                              (cdr ;; Return the second element of the dotted pair returned by ASSOC
  252.  
  253.                                  (assoc 0 ;; Retrieve the dotted pair (or list) with first item equal to 0
  254.  
  255.                                      (entget ent)
  256.                                      ;; Retrieve the DXF data list for the entity name held by the 'ent'
  257.                                      ;; local variable (we know for sure that 'ent' holds an entity name
  258.                                      ;; value, since these expressions will only be evaluated if the test
  259.                                      ;; expression for this condition returns a non-nil value)
  260.  
  261.                                  ) ;; end ASSOC
  262.                                  
  263.                              ) ;; end CDR
  264.  
  265.                          ) ;; end /=
  266.                          
  267.                          (princ "\nInvalid Object Selected.") ;; Else notify the user of invalid object selection
  268.                          
  269.                     ) ;; end IF
  270.                  
  271.                 ) ;; end Condition 2
  272.                
  273.             ) ;; end COND
  274.  
  275.             ;; The last evaluated expression is the COND expression
  276.             ;; COND will in turn return the last evaluated expression of the validated
  277.             ;; Condition, or NIL if no conditions were validated.
  278.             ;;
  279.             ;; If Condition 1 is validated:
  280.             ;;     The value of the PRINC function will be returned; PRINC returns the
  281.             ;;     supplied string argument and hence will return a non-nil value, so the
  282.             ;;     test expression for the WHILE loop is validated and the user is prompted again.
  283.             ;;
  284.             ;; If Condition 2 is validated:
  285.             ;;     The value of the IF function will be returned; IF returns the result
  286.             ;;     of evaluating either the 'then' or 'else' expressions:
  287.             ;;
  288.             ;;     If the 'then' expression is evaluated:
  289.             ;;         The value of the PRINC function is returned up the levels of
  290.             ;;         evaluation, and the WHILE loop is again validated.
  291.             ;;     If the 'else' expression is evaluated:
  292.             ;;         Since there is no 'else' expression, the IF function
  293.             ;;         will return NIL, hence Condition 2 will return NIL, hence
  294.             ;;         COND will return NIL, hence PROGN will return NIL, and so exiting
  295.             ;;         the WHILE loop since the user has selected a valid entity.
  296.             ;;
  297.             ;; If no Conditions are validated:
  298.             ;;     This indicates that the local variable 'ent' does not hold an
  299.             ;;     entity name value, and so must be NIL (since ENTSEL will either
  300.             ;;     return the selection list or NIL [unless keywords are issued])
  301.             ;;     The COND function will now return NIL, and so the PROGN expression
  302.             ;;     will return NIL, exiting the WHILE loop.
  303.            
  304.         ) ;; end PROGN
  305.        
  306.     ) ;; end WHILE
  307.    
  308.     ent
  309.     ;; Evaluate the symbol 'ent'
  310.     ;; Since this is the last expression evaluated, it will be returned by
  311.     ;; the function, since DEFUN returns the value of the last expression evaluated.
  312.     ;;
  313.     ;; Thus, if 'ent' holds an entity name of the type validated by the IF function,
  314.     ;; this entity name will be returned; else 'ent' must be NIL, and so NIL will
  315.     ;; be returned.
  316.    
  317. ) ;; end DEFUN

Please repay the time I that have invested by studying my comments carefully  :-)

bchapman

  • Guest
Re: Help with code to extract a string from text.
« Reply #29 on: February 11, 2013, 09:49:49 PM »
holy begisus