Jump to content

Carriage return in lisp-created MText


robertbon

Recommended Posts

Hello,

 

I have the following lisp which displays the coordinates of a selected point with a leader:

 


(defun c:xy ()
(setq pt (getpoint " Pick Point: "))
(setq x (rtos (car pt)))
(setq y (rtos (cadr pt)))
;(setq z (rtos (caddr pt)))
(setq ptcoord (strcat x "mE, " y "mN"))
(command "QLEADER" pt pause "" "" ptcoord "")
)

 

This give me:

 

"123.45mE, 678.90mN"

 

But I would like:

 

"123.45mE

678.90mN"

 

How do I amend the strcat line so it uses a carriage return?

 

Thanks,

 

Rob

Link to comment
Share on other sites

  • Replies 22
  • Created
  • Last Reply

Top Posters In This Topic

  • Happy Hobbit

    7

  • Lee Mac

    5

  • robertbon

    5

  • Tharwat

    4

Thank you!

 

You're welcome .

 

A few modification if you'd like .

 

(defun c:xy (/ pt)
 (while (setq pt (getpoint "\n Pick Point : "))
   (command "_.QLEADER" "_none" pt "_none" pause "" ""
            (strcat (rtos (car pt)) "mE, \n" (rtos (cadr pt)) "mN") "")
 )
 (princ)
)

Link to comment
Share on other sites

I'd like very much, thanks again.

 

Is there any way to make the text in the Mtext right-justified when it is created or would I have to do that manually?

Link to comment
Share on other sites

Is there any way to make the text in the Mtext right-justified when it is created or would I have to do that manually?

 

Does it mean that you always place the text on the left hand side ?

 

Cause if you place the text on the right side hand with right-justified property of the Mtext , you'd have irregular shape of the Leader .

Link to comment
Share on other sites

  • 2 months later...

I have been using the xy routine above (post 4) with great success, thank you Tharwat.

 

Would somebody be kind enough to help me to enhance this routine?

 

I would like to be able to have it so that it gives the coordinates of the currently selected UCS but creates the text square to the world system. Is this possible?

Link to comment
Share on other sites

I have been using the xy routine above (post 4) with great success, thank you Tharwat.

 

Happy to hear that . :)

 

I would like to be able to have it so that it gives the coordinates of the currently selected UCS but creates the text square to the world system. Is this possible?

 

Can you give an example ( or a drawing ) ?

Link to comment
Share on other sites

This is a little lazy of me, but I need to get to bed :ouch:. There are better ways, perhaps Tharwat might help you with one of them.

 

This takes advantage of the fact that a QLEADER is made up of two entities and the MTEXT is created last.

(defun c:xy ( / el pt rot )
 (setq rot (cons 50 (- (apply 'atan (cdr (reverse (getvar "UCSXDIR")))))))
 (while (setq pt (getpoint "\n Pick Point : "))
   (command "_.QLEADER" "_none" pt "_none" pause "" ""
            (strcat (rtos (car pt)) "mE, [url="file://\\P"]\\P[/url]" (rtos (cadr pt)) "mN") "")
   (entmod (subst rot (assoc 50 (setq el (entget (entlast)))) el))
   )
 (princ)
 )

 

Oh, and I did change the "\n" to "\\P" in the string. Change it back if you want. It just seems to me that most (not all) of the functions floating around the web that extract formatting strings remember "\\P" and forget "\n".

Edited by cwake
Explanation of change to \\P
Link to comment
Share on other sites

Oh, and I did change the "\n" to "\\P" in the string. Change it back if you want. It just seems to me that most (not all) of the functions floating around the web that extract formatting strings remember "\\P" and forget "\n".

 

That's because \n will yield a soft return (shift + enter), whereas \\P is an actual hard carriage return.

Link to comment
Share on other sites

  • 1 year later...
You're welcome .

 

A few modification if you'd like .

 

(defun c:xy (/ pt)
 (while (setq pt (getpoint "\n Pick Point : "))
   (command "_.QLEADER" "_none" pt "_none" pause "" ""
            (strcat (rtos (car pt)) "mE, \n" (rtos (cadr pt)) "mN") "")
 )
 (princ)
)

 

I'm looking to create a similar lisp to the above which inserts a pre-defined mtext string at a given coordinates to use within a separate lisp that I a developing. The mtext will be zero width, text height 2, justified ml & a rotation of zero. This is what I have so far, but I'm stuck :-(

 

(defun c:insmtx ( / a b pt width words )
(Setq width 0) (setq pt (getpoint " 0.0 "))
 (setq a "Bacon &")
 (setq b "Eggs")
(setq words (strcat "A \n" "B"))
 (command "mtext" pt "h" "2" "j" "ml" "R" "0" "S" "STANDARD" "W" width pause "" "" words "")
)

 

Btw I don't really want to insert 'bacon & eggs' into my drawing :)

- Humble Harry

Link to comment
Share on other sites

A couple of points to note:

 

  • Use a conditional expression (if / cond) to test whether the getpoint expression returns a valid point, else, if the user presses Enter or right-clicks at the prompt, getpoint will return nil but the program will still continue (and will likely error).

 

  • The expression (strcat "A \n" "B") is concatenating two literal strings, and will simply return the string "A \nB". If you are looking to concatenate the two variables defined earlier in the code, these will need to appear outside of any quotation marks, i.e. (strcat a " \n" b)

 

  • Some AutoCAD commands can be reliably called from AutoLISP (and sometimes there is no other option), however, certain commands can have unpredictable command prompts (such as the MLEADER command), and so I would suggest using entmake/entmakex or a Visual LISP method where possible.

 

Here are my suggestions for your code:

([color=BLUE]defun[/color] c:insmtx ( [color=BLUE]/[/color] ins )
   [color=GREEN];; Define function, declare local variables[/color]

   ([color=BLUE]if[/color] [color=GREEN];; If the following expression returns a non-nil value[/color]
       ([color=BLUE]setq[/color] ins [color=GREEN];; Bound the value returned by the following expression to the 'ins' symbol and return this value[/color]
           ([color=BLUE]getpoint[/color] [color=MAROON]"\nSpecify insertion point: "[/color]) [color=GREEN];; Prompt the user to specify an insertion point for the MText[/color]
       ) [color=GREEN];; end setq[/color]
       ([color=BLUE]entmake[/color] [color=GREEN];; Append the following DXF data to the drawing database[/color]
           ([color=BLUE]list[/color] [color=GREEN];; Construct a list containing the following DXF data[/color]
              '(000 . [color=MAROON]"MTEXT"[/color])          [color=GREEN];; Entity type[/color]
              '(100 . [color=MAROON]"AcDbEntity"[/color])     [color=GREEN];; Subclass marker[/color]
              '(100 . [color=MAROON]"AcDbMText"[/color])      [color=GREEN];; Subclass marker[/color]
               ([color=BLUE]cons[/color] 10 ins)            [color=GREEN];; Insertion point[/color]
              '(001 . [color=MAROON]"Bacon & \nEggs"[/color]) [color=GREEN];; Content[/color]
              '(040 . 2.0)              [color=GREEN];; Height[/color]
              '(071 . 4)                [color=GREEN];; Justification[/color]
           ) [color=GREEN];; end list[/color]
       ) [color=GREEN];; end entmake[/color]
       [color=GREEN];; Else the user did not provide a valid point[/color]
       ([color=BLUE]princ[/color] [color=MAROON]"\nNo insertion point given, goodbye."[/color])
   ) [color=GREEN];; end if[/color]
   ([color=BLUE]princ[/color]) [color=GREEN];; Suppress the output of the value returned by the last evaluated expression[/color]
) [color=GREEN];; end defun[/color]

Here is a DXF reference to help you to understand the meaning of each DXF group; and here is the reference for the MTEXT entity type.

 

There are other improvements which could be implemented to account for changes to the UCS, the above should at least provide a good starting point for a beginner.

Link to comment
Share on other sites

Wow, I never thought it would have to be so complicated. Thank you very much Lee.

 

Please can you tell me how the resultant of a polar function – within the main lisp I am writing – could be incorporated into this code?

 

Say the resultant is 5,5 My guesstimate is that it would go in the getpoint statement.

Obviously the coordinate would be in a variable

Variable = myvar = 5,5

 

i.e

(getpoint myvar)

 

By the way, is your name actually an acronym for ‘Lisps Excellent Examples Made Always Cleverly’? :-)

Link to comment
Share on other sites

Wow, I never thought it would have to be so complicated.

 

It doesn't have to be, but then it also doesn't have to be robust... the above may initially look daunting, but is relatively simple when studied.

 

Thank you very much Lee.

 

You're most welcome.

 

Please can you tell me how the resultant of a polar function – within the main lisp I am writing – could be incorporated into this code?

 

Say the resultant is 5,5 My guesstimate is that it would go in the getpoint statement.

Obviously the coordinate would be in a variable

Variable = myvar = 5,5

 

The getpoint function is used to prompt the user to specify a point; this function will then return the given point, or nil if the user presses enter or right-clicks at the prompt.

 

If you already have the insertion point (i.e. a list of two or three numerical values), you needn't use the getpoint function (as there is no need to prompt the user), but instead you can simply supply the point as the DXF group 10 value within the list supplied to entmake.

 

The optional point argument for getpoint will cause a 'rubber-band' to be displayed between the cursor and the given point (as a visual aid for the user when specifying a point which relates to another point).

 

By the way, is your name actually an acronym for ‘Lisps Excellent Examples Made Always Cleverly’? :-)

 

Haha! Very good :)

Link to comment
Share on other sites

Thank you very much indeed Lee, you've helped me learn at lot

 

I've sussed it I think. I created a polar function to vaguely mimic the one(s) in the main code

 

 (setq ins (polar '(1 1) 0.785398 1.414214)) 

 

Which gives 2.0 2.0

 

Then put in:

 

(cons 10 ins) 

 

voila! The text is at 2,2

Edited by Happy Hobbit
Working it out produced a good result
Link to comment
Share on other sites

You're welcome Harry.

 

Of course, if the insertion point is a fixed coordinate, the DXF group 10 can be represented as a literal expression, e.g.:

'(10 2.0 2.0 0.0)

(More information about this here)

 

Alternatively, you can calculate the new position more cleanly using mapcar, e.g.:

(cons 10 (mapcar '+ '(1.0 1.0) '(1.0 1.0)))

Of course, given that all data is known in the above example, the above expression is redundant, but I assume that you are obtaining the initial point through other means.

Link to comment
Share on other sites

Sorry about the delay in replying, I've been away for a few days.

 

Unfortunately the coordinates aren’t fixed but vary according to where the entity being draw is placed.

 

I’ve got around that by referencing a part of the new entity (a) then offsetting the mtext with polar:

 

 (setq a-ins (polar a pi 1))

 

Then using ‘a-ins’ for the insertion point for the mtext

 

It works although it’s a little scruffy

Link to comment
Share on other sites

I’ve got around that by referencing a part of the new entity (a) then offsetting the mtext with polar:

 

 (setq a-ins (polar a pi 1))

 

Then using ‘a-ins’ for the insertion point for the mtext

 

It works although it’s a little scruffy

 

There are many ways to achieve the same result in AutoLISP, and that's not too scruffy at all!

 

If you are using the a-ins variable only once, you could omit it entirely and pass the result of the polar expression directly to the cons function, e.g.:

        (entmake ;; Append the following DXF data to the drawing database
           (list ;; Construct a list containing the following DXF data
              '(000 . "MTEXT")          ;; Entity type
              '(100 . "AcDbEntity")     ;; Subclass marker
              '(100 . "AcDbMText")      ;; Subclass marker
               (cons 10 (polar a pi 1)) ;; Insertion point
              '(001 . "Bacon & \nEggs") ;; Content
              '(040 . 2.0)              ;; Height
              '(071 . 4)                ;; Justification
           ) ;; end list
       ) ;; end entmake

 

Other ways to calculate the new position could be:

(cons (1- (car a)) (cdr a))

(mapcar '- a '(1 0 0))

But polar is likely to be the cleanest in this case.

Link to comment
Share on other sites

I like the following:

 

(cons 10 (polar a pi 1)) ;; Insertion point

 

I must admit I hadn't thought of that

 

It is only used once, so I'll try that.

 

Although I'm intrigued by the other two options, I'll have to look them up to understand them.

 

car = beginning of list (what list?)

 

cdr = end of list (what list?)

 

As for mapcar, forget it

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...