(defun c:mchar
( / e1 e2 no s1 s2 sl
) ;; Define function, declare local variables
(if ;; If the following expression returns a non-nil value
(and ;; All of the following expressions must return a non-nil value for AND to return T
(setq e1
;; Assign the return of the LM:SELECTIFOBJECT function to the local variable 'e1'
(LM:SelectifObject "\nSelect 1st Text: " "TEXT")
;; Call the LM:SELECTIFOBJECT function with the two required arguments
;; Here, the 'msg' parameter is passed the string value "\nSelect 1st Text: "
;; and the 'obj' parameter is passed the string value "TEXT"
;;
;; At this point we needn't know how this function operates, only that it requires
;; a prompt message argument and an entity type string argument, and that it returns
;; the entity name of a valid selected entity, or NIL if the user fails to select a
;; valid entity.
;;
;; View the LM:SELECTIFOBJECT function as just another AutoLISP function; imagine
;; that you don't have access to the function definition. Consider that you don't have access
;; to the inner workings of the SETQ function, however, you know that SETQ requires
;; a set of symbol and value pairs, and will return the value of the last pair.
) ;; end SETQ
(setq e2
;; Assign the return of the LM:SELECTIFOBJECT function to the local variable 'e2'
(LM:SelectifObject "\nSelect 2nd Text: " "TEXT")
;; Call the LM:SELECTIFOBJECT function with the two required arguments
;; Now, the 'msg' parameter is passed the string value "\nSelect 2nd Text: "
;; and the 'obj' parameter is again passed the string value "TEXT"
) ;; end SETQ
(progn ;; Evaluate the following expressions and return the result of the last expression evaluated
(initget 6) ;; Reject zero & negative values (bits 1 & 2)
(setq no
;; Assign the return of the GETINT function to the local variable 'no'
(getint "\nNumber of Characters: ")
;; Prompt the user for a number of characters to remove.
;; Since this is the first user-input function to follow the INITGET expression
;; the user input will be restricted to positive non-zero integers.
) ;; end SETQ
;; The SETQ expression is the last expression evaluated within the PROGN expression
;; and hence the result of this expression is returned by the PROGN expression and
;; evaluated by the AND function.
) ;; end PROGN
) ;; end AND
(progn ;; Evaluate the following expressions and return the result of the last expression evaluated
(setq e1
;; Assign the return of the ENTGET function to the local variable 'e1' (overwriting its previous value)
;; Retrieve the list of DXF data for the entity name assigned to the local variable 'e1'
;; We know that variable 'e1' will definitely hold an entity name value, since
;; otherwise the AND expression would not be satisfied and the 'then' expression
;; for the IF function would not be evaluated.
e2 ;; Assign the return of the ENTGET function to the local variable 'e2' (overwriting its previous value)
;; Note that the SETQ function can be passed multiple symbol/value pairs, however only the value of
;; the last pair will be returned, hence it was necessary to separate the SETQ statements within
;; the AND expression to ensure every pair held a non-nil value.
;; Retrieve the list of DXF data for the entity name assigned to the local variable 'e2'
s1 ;; Assign the return of the CDR function to the local variable 's1'
(cdr ;; Return the second element of the DXF dotted pair (see the documentation on the CDR function)
;; Retrieve the dotted pair (or list) with first item equal to 1 from the DXF data list
;; assigned to local variable e1 (i.e. the text content of the first text entity).
;; Since DXF Group code 1 holds a string value, the return will be a dotted pair, e.g.:
;; (1 . "String")
) ;; end CDR
s2 ;; Assign the return of the CDR function to the local variable 's2'
(cdr ;; Return the second element of the DXF dotted pair (see the documentation on the CDR function)
;; Retrieve the dotted pair (or list) with first item equal to 1 from the DXF data list
;; assigned to local variable e2 (i.e. the text content of the second text entity).
) ;; end CDR
) ;; end SETQ
(if ;; If the following expression returns a non-nil value
(< ;; Returns T if each argument is numerically less than the argument to its right
no ;; Number of characters as specified by the user
(setq sl
;; Assign the return of the STRLEN function to the local variable 'sl'
(strlen s1
) ;; Retrieve the number of characters of the text content of the first text entity
) ;; end SETQ
;; Here we are testing whether the number of characters to be moved
;; is less than the string length of the string held by the first text entity
;; The string length is assigned to local variable 'sl' as it will be used later
;; the program, hence improving efficiency.
) ;; end <
(progn ;; Evaluate the following expressions and return the result of the last expression evaluated
(entmod ;; Modify the DXF data in the drawing database for the following DXF data list
(subst ;; Substitute the following for every occurrence of the second argument in the list supplied
(cons 1 ;; Construct a dotted pair with first element equal to 1
;; Return a section of the string held by the 's1' variable (i.e. the content
;; of the first text entity), beginning at character 1 (the first character)
;; and spanning a number of characters equal to the string length minus the number
;; of characters to be removed
) ;; end CONS
;; Retrieve the dotted pair to be replaced in the DXF data list
;; Note that this could alternatively be (cons 1 s1)
e1 ;; The DXF data list in which the dotted pair substitution is to be made
) ;; end SUBST
) ;; end ENTMOD
(entmod ;; Modify the DXF data in the drawing database for the following DXF data list
(subst ;; Substitute the following for every occurrence of the second argument in the list supplied
(cons 1 ;; Construct a dotted pair with first element equal to 1
(strcat ;; Concatenate the following strings
;; Return a section of the string held by the 's1' variable (i.e. the content
;; of the first text entity), beginning at the character whose number is
;; given by the string length minus the number of characters to be removed
;; minus minus 1 (i.e. add one), spanning the remaining characters in the
;; string.
" " ;; Include a space between the added characters and the existing content
s2 ;; The existing text content of the second text entity
) ;; end STRCAT
) ;; end CONS
;; Retrieve the dotted pair to be replaced in the DXF data list
;; Note that this could alternatively be (cons 1 s2)
e2 ;; The DXF data list in which the dotted pair substitution is to be made
) ;; end SUBST
) ;; end ENTMOD
) ;; end PROGN
(princ "\nText is shorter than number of characters.") ;; Else notify the user of invalid input
) ;; end IF
) ;; end PROGN
;; Here we could notify the user that they either haven't selected one or more text entities
;; or that they haven't specified a number of characters, however, they already know that...
) ;; end IF
(princ) ;; Suppress the return of the last evaluated expression (in this case, the IF function)
) ;; end DEFUN, function is defined
;; Select if Object - Lee Mac
;; Continuously prompts the user for a selection of a specific object
(defun LM:SelectifObject
( msg obj
/ ent
) ;; Define function, declare required arguments and local variables
;; In this case, the function requires two arguments, the values of
;; which will be held by the parameters 'msg' & 'obj'
(while ;; while the following returns a non-nil value
(progn ;; Evaluate the following expressions and return the result of the last expression evaluated
(setvar 'errno
0) ;; Reset the ERRNO System Variable to zero
(setq ent
;; Assign the return of the CAR function to the local variable 'ent'
(car ;; Return the first item of the list returned by ENTSEL (or return nil)
;; Evaluate the ENTSEL function with the optional prompt argument
;; taking the value held by the 'msg' parameter supplied to the LM:SELECTIFOBJECT function
) ;; end CAR
) ;; end SETQ
;; Evaluate the test expression for each condition and evaluate the expressions following
;; the test expression for the first test expression returning a non-nil value
( ;; Condition 1 - the parenthesis spacing is purely aesthetic
;; Test whether the ERRNO System Variable equals 7
;; (i.e. a missed selection - the user clicked empty space)
(princ "\nMissed, try again.") ;; if ERRNO = 7, notify user has missed the selection
) ;; end Condition 1
( ;; Condition 2
;; Test whether the local variable 'ent' points to a value of
;; ename type (entity name)
;; Variable 'ent' has entity name value, so...
(if ;; If the following expression returns a non-nil value
(/= ;; Returns T if no two successive arguments are equal
obj ;; The entity type string argument passed to the LM:SELECTIFOBJECT function
(cdr ;; Return the second element of the dotted pair returned by ASSOC
(assoc 0 ;; Retrieve the dotted pair (or list) with first item equal to 0
;; Retrieve the DXF data list for the entity name held by the 'ent'
;; local variable (we know for sure that 'ent' holds an entity name
;; value, since these expressions will only be evaluated if the test
;; expression for this condition returns a non-nil value)
) ;; end ASSOC
) ;; end CDR
) ;; end /=
(princ "\nInvalid Object Selected.") ;; Else notify the user of invalid object selection
) ;; end IF
) ;; end Condition 2
) ;; end COND
;; The last evaluated expression is the COND expression
;; COND will in turn return the last evaluated expression of the validated
;; Condition, or NIL if no conditions were validated.
;;
;; If Condition 1 is validated:
;; The value of the PRINC function will be returned; PRINC returns the
;; supplied string argument and hence will return a non-nil value, so the
;; test expression for the WHILE loop is validated and the user is prompted again.
;;
;; If Condition 2 is validated:
;; The value of the IF function will be returned; IF returns the result
;; of evaluating either the 'then' or 'else' expressions:
;;
;; If the 'then' expression is evaluated:
;; The value of the PRINC function is returned up the levels of
;; evaluation, and the WHILE loop is again validated.
;; If the 'else' expression is evaluated:
;; Since there is no 'else' expression, the IF function
;; will return NIL, hence Condition 2 will return NIL, hence
;; COND will return NIL, hence PROGN will return NIL, and so exiting
;; the WHILE loop since the user has selected a valid entity.
;;
;; If no Conditions are validated:
;; This indicates that the local variable 'ent' does not hold an
;; entity name value, and so must be NIL (since ENTSEL will either
;; return the selection list or NIL [unless keywords are issued])
;; The COND function will now return NIL, and so the PROGN expression
;; will return NIL, exiting the WHILE loop.
) ;; end PROGN
) ;; end WHILE
ent
;; Evaluate the symbol 'ent'
;; Since this is the last expression evaluated, it will be returned by
;; the function, since DEFUN returns the value of the last expression evaluated.
;;
;; Thus, if 'ent' holds an entity name of the type validated by the IF function,
;; this entity name will be returned; else 'ent' must be NIL, and so NIL will
;; be returned.
) ;; end DEFUN