See the top rated post in this thread. Click here

Results 1 to 10 of 10

Thread: AutoLISP 101

  1. #1
    Past Vice President / AUGI Volunteer peter's Avatar
    Join Date
    2000-09
    Location
    Honolulu Hawaii
    Posts
    1,026
    Login to Give a bone
    3

    Default AutoLISP 101

    Comments and Headers


    Please post comments to discussion thread

    The first place I would like to start is comments.

    I have adopted a standard where all of my lisp libraries and routines have a file header and function header comments.

    The file header includes
    1.) My name and year for copyright
    2.) A disclaimer prohibiting unauthorized use
    3.) An abstract that describes what is the purpose of the file or library
    4.) The command line functions with descriptions (alphabetically) including hot key assignments
    5.) The general functions with descriptions
    6.) Version or last modified date

    The function headers include
    1.) Function Description

    The functions are alphabetical (although I let the hot keys supersede their respective functions)

    I use a noun first verb last function name to help organize the functions together when alphabetical.

    I will talk more about function and variable naming.

    So be honest how many of you actually take the time to create a LISP file header?

    Code:
    ;___________________________________________________________________________________________________________|
    ;
    ; Written By: Peter Jamtgaard copyright 2017 All Rights Reserved
    ;___________________________________________________________________________________________________________|
    ;
    ; Any use by unauthorized person or business is strictly prohibited.
    ;___________________________________________________________________________________________________________|
    ; 
    ; Abstract: This routine will display an alert dialog with the words "Hello World" in it.
    ;___________________________________________________________________________________________________________|
    ;
    ; Command Line Function Header List
    ;___________________________________________________________________________________________________________|
    
    ;  Function and Description
    
    ;* C:HW 
    ;* Command Line Function (or hot key) to display Hello World Dialog
    
    ;* C:HelloWorld
    ;* Command Line Function to display Hello World Dialog
    
    ;___________________________________________________________________________________________________________|
    ;
    ; General Function Header List 
    ;___________________________________________________________________________________________________________|
    
    ;  Function, Arguments and Description
    
    ;* (DialogAlertHelloWorld)
    ;* Function to Display an Alert box with the words "Hello World"
    
    ;___________________________________________________________________________________________________________|
    ;
    ; Include Libraries List
    ;___________________________________________________________________________________________________________|
    
    ;* None
    
    ;___________________________________________________________________________________________________________|
    ;
    ; Include Data File List
    ;___________________________________________________________________________________________________________|
    
    ;* None
    
    ;___________________________________________________________________________________________________________|
    ;
    ; Include Dialog Control Language File List
    ;___________________________________________________________________________________________________________|
    
    ;* None
    
    ;$ End Header
    ;___________________________________________________________________________________________________________|
    ___________________________________________________________________________________________________________|
    ;
    ; Command Line Functions
    ;___________________________________________________________________________________________________________|
    ;
    ; Command Line Function to display Hello World Dialog
    ;___________________________________________________________________________________________________________|
    
    (defun C:HW ()(C:HelloWorld))
    
    (defun C:HelloWorld ()(DialogAlertHelloWorld))
    
    ;___________________________________________________________________________________________________________|
    ;
    ; Function to display Hello World Dialog in Alert Dialog Box
    ;___________________________________________________________________________________________________________|
    
    (defun DialogAlertHelloWorld ()(Alert "Hello World"))
    
    ;___________________________________________________________________________________________________________|
    ;___________________________________________________________________________________________________________|
    
    (princ "!")
    (vl-load-com)
    Attached Files Attached Files
    Last edited by peter; 2017-06-29 at 12:47 AM.
    AutomateCAD

  2. #2
    Past Vice President / AUGI Volunteer peter's Avatar
    Join Date
    2000-09
    Location
    Honolulu Hawaii
    Posts
    1,026
    Login to Give a bone
    0

    Default Re: AutoLISP 101

    Defining Functions

    Please post comments to discussion thread

    The next topic I want to cover is defining functions or the define function expression.

    I call AutoLISP functions expressions.

    Like Defun is an expression, which is short for Define Function.

    There are two kinds of Define Function types.

    Those that start with C: which are available at the command line and those that do not have C:

    Code:
    (defun C:HelloWorld ()(alert "Hello World"))
    If you cut and paste that into the command line will create a new command "HelloWorld" without quotes at the command prompt.
    You can also put it into a notepad file and call it HelloWorld.lsp (for example) and load it into AutoCAD with (load "Helloworld")

    or

    Code:
    (defun HelloWorld ()(alert "Hello World"))
    Without the C: you can still run this at the command line but you need to wrap it with parenthesis "(HelloWorld)" without quotes

    While we are discussing the defun expression we should discuss arguments and local/global variables.

    An argument(s) are values that are passed to a function that are defined in the defun expression.

    Code:
    (defun DivideBy3 (Value)(/ Value 3.0))
    Here I create a simple function that divides a number by 3.0.

    I would call that function from another function like this

    Code:
    (divideby3 12)
    returns 4.0

    You can have more than one argument to a function too.

    If we create a variable inside of a routine we use the setq expression

    like

    (setq Result 12)

    If we do not localize the variable to the function it is in, the variable will be persistent and become a global variable.

    The way we free the memory after a function is run for the variables inside it is by localizing the variable.


    Code:
    (defun DivideBy3 (Value / Result)(setq Result (/ Value 3.0)))
    Adding the forward slash after the argument allows us to localize the variables.
    Code:
    (defun NAME (argument1 argument2 / localvariable1 localvariable2)(....   ))
    and for command line functions

    Code:
    (defun C:NAME (/ localvariable1 localvariable2)(....   ))
    The expressions discussed above were defun and setq

    The concepts discussed are define function types, arguments and local variables.

    It is good programming technique to always localize your variables unless it is absolutely necessary to have global variables.
    Last edited by peter; 2017-06-29 at 06:33 PM.
    AutomateCAD

  3. #3
    Past Vice President / AUGI Volunteer peter's Avatar
    Join Date
    2000-09
    Location
    Honolulu Hawaii
    Posts
    1,026
    Login to Give a bone
    0

    Default Re: AutoLISP 101

    Defined Functions


    Please post comments to discussion thread

    The next topic I want to cover is a way to check all of the defined functions.

    In the example below I am jumping a little ahead, but I will come back and discuss the lisp expressions I use in more depth later.

    In the C:LISPFunctions command line routine below I prompt the user for a wildcard string to match functions to.

    To prompt the user I use the getstring expression and the prompt includes a "\n" which means carriage return or new line.

    I then call the LISPFunctions function with wildcard string argument.

    Wildcard strings include all characters and numbers, but special characters like "*", "#", and "?"

    "*" means any string including "" and could be multiple characters long like

    (wcmatch "FRED" "F*") would return T

    "#" is any single numeral and "?" is any single character.

    Notice the atoms-family expression will give you a list of ALL loaded LISP functions.

    I will come back and discuss conditional (if and cond statements), loops (foreach expressions) and string manipulation functions
    like (strcat ...) in upcoming posts.

    Try running this routine and put VLA-GET-* at the prompt.

    It is always good to know what defined functions are loaded!

    Code:
    ;___________________________________________________________________________________________________________|
    ;
    ; Written By: Peter Jamtgaard copyright 2017 All Rights Reserved
    ;___________________________________________________________________________________________________________|
    ;
    ; Any use by unauthorized person or business is strictly prohibited.
    ;___________________________________________________________________________________________________________|
    ; 
    ; Abstract: This routine will display a list of loaded lisp functions that match a Wildcard String
    ;___________________________________________________________________________________________________________|
    ;
    ; Command Line Function Header List
    ;___________________________________________________________________________________________________________|
    
    ;  Function and Description
    
    ;* C:LF 
    ;* Command Line Function (or hot key) to display list of loaded LISP expressions matching a Wildcard String
    
    ;* C:LISPFunctions
    ;* Command Line Function to display Hello World Dialog
    
    ;___________________________________________________________________________________________________________|
    ;
    ; General Function Header List 
    ;___________________________________________________________________________________________________________|
    
    ;  Function, Arguments and Description
    
    ;* (LispFunctions strWCMatch)
    ;* Function to return a list of loaded lisp expressions (functions) that match a Wildcard String
    
    ;$ End Header
    ;___________________________________________________________________________________________________________|
    ;
    ; Command Line Functions
    ;___________________________________________________________________________________________________________|
    ;
    ; Command Line Function to display Hello World Dialog
    ;___________________________________________________________________________________________________________|
    
    (defun C:LF ()(C:LISPFunctions))
    
    (defun C:LISPFunctions (/ strFunction strWCMatch)
     (setq strWCMatch (getstring "\nEnter Wildcard Match String: "))
     (foreach strFunction (LispFunctions strWCMatch)
      (princ (strcat "\n" strFunction))
     ) 
     (textscr)
     (princ)
    )
    
    ;___________________________________________________________________________________________________________|
    ;
    ; General Functions
    ;___________________________________________________________________________________________________________|
    ;
    ; Function to return a list of loaded lisp expressions (functions) that match a Wildcard String
    ;___________________________________________________________________________________________________________|
    
    
    (defun LISPFunctions (strWCMatch / lstFunctions strFunction)
     (foreach strFunction (atoms-family 1) 
      (if (wcmatch (strcase strFunction)  (strcase strWCMatch ))
       (setq lstFunctions (cons strFunction lstFunctions))
      )
     )
     (if lstFunctions
      (acad_strlsort lstFunctions)
     )
    )
    
    (princ "!")
    (vl-load-com)
    Attached Files Attached Files
    Last edited by peter; 2017-06-29 at 06:37 PM.
    AutomateCAD

  4. #4
    Past Vice President / AUGI Volunteer peter's Avatar
    Join Date
    2000-09
    Location
    Honolulu Hawaii
    Posts
    1,026
    Login to Give a bone
    0

    Default Re: AutoLISP 101

    Variables Types


    Please post comments to discussion thread

    in AutoLISP (we will talk about VL later)

    A variable is a container to store a value. The kind of value is a variable type. The descriptions of the variables are listed below.

    Code:
    Boolean
    Dotted Pair
    Entity
    Integer
    List
    Real (single)
    Selection Set
    String
    In AutoLISP you have the above list of variable types

    You can create and set the value of a variable using the following couple options

    Code:
    (setq intVariable 1)
    (set 'intVariable 1)
    If you are not familiar with the set expression is because most programmers use the setq instead.

    The nice thing about set is you can have the program create its own variable names. (VB.net, C# and C++ cannot.)

    Variable naming

    I prefer to use a naming style that is similar to the Reddick Naming Convention used in VB.

    The variable names using this style include a 2 or 3 letter prefix like ss (for selection set) or int (for integer) that describes the variable type.

    The rest of the name is a clear descriptions of the contents like ssSelections, intCount, strFullName, lstObjects etc...

    I use the same name consistently to help me be able to immediately understand the variable.

    I avoid using abbreviations in my names and only use single letter variables in lambda expressions.

    Variable Types:

    Boolean is a true/false variable but in LISP it is T/nil

    T is a true atom and nil is nothing.

    Example boolean variable name: blnFlag

    Dotted Pair is a special kind of two item list.

    It is used in entity lists frequently (which we talk about later) but I try to avoid it.

    The first item is available using the (car dprPair) and the second item is available using (cdr dprPair)

    This is not true for lists where the second item is available by (cadr lstPair)

    I will talk more about lisp manipulation later.

    Example dotted pair variable name: dprPair

    Entity is a pointer that allows the programmer to access and modify entities in memory.

    Example entity name variable name: entSelection

    Integer is a whole number +32767 to -32678 for some expressions (like ssname) and +2,147,483,647 to -2,147,483,648 for others.

    I just assume the lower range.

    Example integer variable name: intCount

    List

    A list is a powerful variable type that can contains a list of other variables including other lists!

    for example (list "A" "B" "C" 1 2 3 1.0 2.0 3.0 (list "a" "b")) is valid.

    The Visual Studio programming languages have difficulty mixing variable types but LISP doesn't.

    Example list variable name: lstSelections

    Real numbers are 16 decimal places (max) positive and negative single precision real numbers.

    Example real number variable name: sngValue

    Selection Set is a lisp variable type that is created by the ssget expression.

    Example selection set variable name: ssSelections

    It is a series (not a list) of entityname that can be indexed and read using the ssname expression.

    String is a variable that contains a series of alpha numeric characters.

    WHen you create them you need to place double quotes at the start and finish of the series

    Example: "This is an example of a string"

    Example string variable name: strFullName

    There are more variables in Visual LISP but this is a good place to start.

    If you don't understand any of them I would suggest researching them more.

    Also the variable naming is a personal preference option.

    There is good reason to use very descriptive naming that you will see later.

    Good consistent habits pay great dividends later!!!

    http://forums.augi.com/showthread.ph...33#post1327633
    Last edited by peter; 2017-06-30 at 06:24 PM.
    AutomateCAD

  5. #5
    Past Vice President / AUGI Volunteer peter's Avatar
    Join Date
    2000-09
    Location
    Honolulu Hawaii
    Posts
    1,026
    Login to Give a bone
    2

    Default Re: AutoLISP 101

    Conditionals

    Please post comments to discussion thread


    http://forums.augi.com/showthread.ph...61#post1327661

    Here is where we talk about nothing! or nil in lisp terminology.

    There are a few functions that respond to nil (and/or T or a value)


    The If expression, the cond expression (condition), the not expression, the and expression and or expression.

    IF expression

    The if expression will return the first option if T (true) or any other value is supplied as the first argument.
    The if expression will return the second option if nil is supplied as the first argument.

    For example

    Code:
    (If nil 
     (princ "\nFirst Expression!")
     (princ "\nSecond Expression!")
    )
    Would print to the command line a carriage return and "Second Expression!"

    Progn Expression

    The progn expression is typically used in if expressions if you want to do more than on expression

    Code:
    (If nil 
     (progn
      (princ "\nFirst Expression!")
      (princ "...")
     )
     (progn
      (princ "\nSecond Expression!")
      (princ "...")
     )
    )
    Would print to the command line a carriage return and "Second Expression!..."

    Cond Expression

    Code:
    (cond (nil (princ "\nNot This One: "))
            (nil (princ "\nNot This One either: "))
            (T (princ "\nYep This One: "))  
    )
    Now putting nil or T in a conditional doesn't make a lot of sense so most programmers use conditionals with tests.

    Tests for numbers can be /=, <=, =, >=

    For the examples lets use a very simple variable (setq X 1)

    You can also use more than 2 arguments in these expressions!

    Examples:

    /= Expression

    (/= 1 2) would return T

    (/= 1 X) would return nil

    (/= 1 2 3) would return T

    <= Expression

    (<= 1 2) would return T

    (<= 1 X) would return nil

    (<= 1 2 3) would return T

    = Expression

    (= 1 2) would return nil

    (= 1 X) would return T

    (= 1 2 3) would return nil

    >= Expression

    (>= 1 2) would return nil

    (>= 1 X) would return T

    (>= 3 2 1) would return T

    Now you might want to do more than one test in your logic so you would use AND or OR expressions

    And Expression

    Code:
    (and (> X 0)
           (< X 2)
           (= X 1)
    )
    would return a true

    Or Expression

    Code:
    (or (< X 0)
        (> X 2)
        (/= X 2)
    )
    would return a true (not equal to 2)

    I prefer to use And and Or without if expressions (I will show you later how to do that)

    Not Expression

    (not nil) returns T

    (not 1) returns nil

    I wanted to do loops first but I think conditionals are essential to exploring loops
    Last edited by peter; 2017-07-02 at 04:20 AM.
    AutomateCAD

  6. #6
    Past Vice President / AUGI Volunteer peter's Avatar
    Join Date
    2000-09
    Location
    Honolulu Hawaii
    Posts
    1,026
    Login to Give a bone
    1

    Default Re: AutoLISP 101

    Loops

    Please post comments to discussion thread

    http://forums.augi.com/showthread.ph...67#post1328567

    Loops are necessary in programming to process groups of data or in AutoCAD selection sets or items of lists.

    Those loop functions include Foreach, Mapcar, Repeat and While. (In Visual LISP you also have Vlax-For which we will discuss later)

    LISP stands for list Processing.

    The first two expressions Foreach and Mapcar are for lists.

    Say we make a list like this

    Code:
    (setq lstLetters (list "a" "b" "c" "d" "e"))

    Foreach


    We can iterate (process each value of the list) like this

    Code:
    (foreach strLetter lstLetters (print strLetter))
    would print each letter out to the command line like

    "a"
    "b"
    "c"
    "d"
    "e"

    Mapcar
    (Multiple APplications to the Contents of the Address Register)

    Which means do this function to each member of the list.
    Code:
    (mapcar 'print lstLetters)
    Would also print each letter out to the command line like

    "a"
    "b"
    "c"
    "d"
    "e"

    I might mention here the mysterious function Lambda.

    Lambda is almost exactly the same at the well known function Defun (define function)

    The only difference is Lambda doesn't have a function name and it runs immediately.

    It is frequently used with the Mapcar function.

    So

    Code:
    (mapcar '(lambda (X)(print X)) lstLetters)
    This does the exact same thing as the examples above

    But it allows you to perform more complicated functions like

    Code:
    (mapcar '(lambda (X)(print (strcat "+" X))) lstLetters)
    Would print each letter out to the command line like

    "+a"
    "+b"
    "+c"
    "+d"
    "+e"

    It can also handle multiple lists too.

    (setq lstNumerals (list "1" "2" "3" "4" "5"))
    Code:
    (mapcar '(lambda (X Y)(print (strcat  X Y))) lstLetters lstNumerals)
    Would print each letter out to the command line like

    "a1"
    "b2"
    "c3"
    "d4"
    "e5"

    OK enough about Mapcar.

    Repeat


    Repeat will repeat a section of code.

    For example

    Code:
    (setq intCount 0)
    (repeat 5
     (setq intCount (1+ intCount))
     (print intCount)
    )
    The 1+ expression adds one to the intCount variable each time it loops.

    Would print each letter out to the command line like

    1
    2
    3
    4
    5

    The repeat expression is frequently used to read and process a selection set like this function (we will talk more about
    selection set expressions later in the series.

    Code:
    ;___________________________________________________________________________________________________________|
    ;
    ; Function to convert a selection set to a list of entities
    ;___________________________________________________________________________________________________________|
    
    (defun SelectionSetToListOfEntities (ssSelections / intCount entSelection lstEntities )
     (repeat (setq intCount (sslength ssSelections))
      (setq intCount (1- intCount))
      (setq entSelection (ssname ssSelections intCount))
      (setq lstEntities     (cons entSelection lstEntities))
     )
     lstEntities
    )

    While


    The while expression will perform a conditional and keep looping until the condition is false for example

    Code:
    ;___________________________________________________________________________________________________________|
    ;
    ; Function to convert a selection set to a list of entities
    ;___________________________________________________________________________________________________________|
    
    (defun SelectionSetToListOfEntities (ssSelections / intCount intCountLength entSelection lstEntities )
     (setq intCountLength (sslength ssSelections))
     (setq intCount intCountLength)
     (while (> intCount 0)
      (setq intCount (1- intCount))
      (setq entSelection (ssname ssSelections intCount))
      (setq lstEntities     (cons entSelection lstEntities))
     )
     lstEntities
    )
    Please ask me questions and ask for more examples if this is not clear for you on the discussion thread.
    AutomateCAD

  7. #7
    Active Member Tommybluegrass's Avatar
    Join Date
    2015-12
    Location
    Mississippi Gulf Coast, U.S.A.
    Posts
    74
    Login to Give a bone
    0

    Default Re: AutoLISP 101

    Nice Peter - Good Job

  8. #8
    Past Vice President / AUGI Volunteer peter's Avatar
    Join Date
    2000-09
    Location
    Honolulu Hawaii
    Posts
    1,026
    Login to Give a bone
    0

    Default Re: AutoLISP 101

    Entity Names

    Please post comments to discussion thread

    http://forums.augi.com/showthread.ph...80#post1329480

    Entities are necessary for manipulating data in drawing files.

    All graphic items (lines, circles, etc...) are entities.

    Useful Entity Functions

    Code:
    (entlast)
    will return the last graphic entity in a drawing.

    Code:
    (handent "1C7")
    will return the entity associated with the unique hexadecimal identifier called a handle.

    Code:
    (entsel)
    will prompt the user to select an object and return a list with two items including the entityname the point selected.

    So...

    Code:
    (car (entsel))
    will return a selected objects entity name (car returns the first item in a list)

    So to get and store an entityname you use the setq expression.

    Code:
    (setq entSelection (car (entsel "\nSelect One Item: ")))
    the entsel expression allows for a prompt ("\n" is a carriage return)

    The default prompt is "Select objects:"

    There is also

    Code:
    (setq entSelectionNested (car (nentsel "\nSelect nested item: ")))
    Which allows the user to select items nested inside other items (like blocks)

    Try it and comment to the discussion thread.
    AutomateCAD

  9. #9
    Past Vice President / AUGI Volunteer peter's Avatar
    Join Date
    2000-09
    Location
    Honolulu Hawaii
    Posts
    1,026
    Login to Give a bone
    1

    Default Re: AutoLISP 101

    Command Expressions (basic error handling and local functions)

    Please post comments to discussion thread

    http://forums.augi.com/showthread.ph...65#post1329565

    Before I dig into entity lists....

    I thought I might talk a little about the command expression (and command-s and vl-cmdf too)

    They allow the user to run AutoCAD commands, which sometimes can do things that LISP (or VisualLISP) cannot do.

    To me it is the LAST choice to do something.

    I prefer to use ActiveX, then entity methods and finally the command pipe (or throat).


    So how can we use the command expression.

    Code:
    (command "line" pause pause "")
    The pause argument waits for user input or selection.

    If you do not like to see the prompts you can set the system variable "cmdecho" to 0 (or 1 to see)

    That way you can add your own prompts.

    Code:
    (defun C:L1 (/ intCMDEcho)
     (setq intCMDEcho (getvar "cmdecho"))
     (setvar "cmdecho" 0)
     (command "line" pause pause "")
     (setvar "cmdecho" intCMDEcho)
    )
    The only problem with this is escaping the command expression will cause the cmdecho to remain off.

    So the following code includes an error function that runs if you escape the command expression and
    changes the system variable back to the original value. This is also a good example of creating a local
    function inside another function.

    Code:
    (defun C:L1 (/ intCMDEcho *Error*)
     (defun *Error* (X)
      (setvar "cmdecho" intCMDEcho)
     )
     (setq intCMDEcho (getvar "cmdecho"))
     (setvar "cmdecho" 0)
     (command "line" pause pause "")
     (setvar "cmdecho" intCMDEcho)
    )
    In there are both the Command-S and VL-Cmdf expressions that are similar syntax.

    VL-cmdf is nice because it check to make sure the expression works before running it so I use it.

    You need to run the (vl-load-com) expression to load VisualLISP.

    I just make it the very last line of code in my files like.

    Code:
    (defun C:L1 (/ intCMDEcho *Error*)
     (defun *Error* (X)
      (setvar "cmdecho" intCMDEcho)
     )
     (setq intCMDEcho (getvar "cmdecho"))
     (setvar "cmdecho" 0)
     (vl-cmdf "line" pause pause "")
     (setvar "cmdecho" intCMDEcho)
    )
    (vl-load-com)
    Last edited by peter; 2017-09-13 at 05:54 PM.
    AutomateCAD

  10. #10
    Woo! Hoo! my 1st post
    Join Date
    2017-12
    Posts
    1
    Login to Give a bone
    0

    Default Re: AutoLISP 101

    hello, im new here. i have been all over the web and anywhere else i could go and anyone i could talk to about the lisp. i work in civil 3d and i play with fiber optics drawing. ive been in this field for about a year and a half. ive noticed that it is a time consuming mo-fo if i have to add a page or just have to change a number in the match line. a lot of what i do is copy past and manipulate the objects in the drawing. i am asking for assistance/ a script that can number multiple matchlines throughout multiple layout tabs. if you could assist in any way even just pointing me in the right direction would be wonderful and a Christmas dream come true. thank you for your time i hope someone can assist me

Similar Threads

  1. Add Schedule Headers to Existing Grouped Headers
    By Wish List System in forum Revit MEP - Wish List
    Replies: 0
    Last Post: 2015-04-22, 03:24 PM
  2. Structural Headers
    By ford347 in forum Revit Architecture - General
    Replies: 9
    Last Post: 2007-07-11, 04:51 PM
  3. Headers
    By rick.74802 in forum Revit Architecture - General
    Replies: 3
    Last Post: 2004-10-20, 03:13 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •