AutoLisp -> MakeEnt To Generate Text String

AutoLisp -> MakeEnt To Generate Text String

audioGPQBX
Participant Participant
2,086 Views
10 Replies
Message 1 of 11

AutoLisp -> MakeEnt To Generate Text String

audioGPQBX
Participant
Participant

I am trying to create a lisp routine that will insert a plain text string. I like the ENTMAKE with DXF values solution. The goal is to pick a point and a text string is inserted at the pick point.

 

Test1 command is what I have so far. I am missing something on the insertion point. The text comes in at 0.0.0

 

(defun c:test1 (/ pt-xy)
(setq pt-xy (getpoint " Text Insertion Point"))
(if pt-xy
(progn
(ENTMAKE
(LIST
(CONS 0 "TEXT")
(CONS 100 "AcDbEntity")
(CONS 100 "AcDbMText")
(CONS 10 pt-xy)
(cons 40 0.100)
(CONS 41 1.0)
(CONS 72 0)
(CONS 1 "Text 1 Here")
(CONS 7 "TOM")
(CONS 8 "LAY02")
(CONS 73 3)
); close list
); close entmake
); close progn
); close if pt-zx
(princ)
); close defun

 

I understand (Cons 10 pt-xy) is wrong. As written, it places the text at insertion = 0,0,0. Everything else I have tried has produced worse results.

 

I have a compareable Mtext routine that works very well.  

 

And yes, I have the 270 page .PDF  AutoCAD DXF reference. I have been through it several times, to the best of my comprehension. Do not present this as a solution.

0 Likes
Accepted solutions (1)
2,087 Views
10 Replies
Replies (10)
Message 2 of 11

ВeekeeCZ
Consultant
Consultant

Nono, there is a trick. If you have (could be omitted) some justification (as 73 or 72) you need to also have 11 with the same point as 10.

 

(CONS 100 "AcDbMText") should be "AcDbText".... but it seems not failing.

Also be aware that you need to be sure that your style (7) is defined in your drawing, otherwise it fails.

 

Look HERE for the necessary minimum definition.

 

Possibly like this

 

(defun c:test1 (/ p)
  
  (if (and (or (tblsearch "STYLE" "TOM")
	       (alert "Error! 'TOM' Text style not defined in the drawing!"))
	   (setq p (getpoint "\nPlace the text: "))
	   )
    (entmake
      (list '(0 . "TEXT")
	    (cons 10 p)
	    (cons 11 p)
	    '(40 . 0.1)
	    '(41 . 1.)
	    '(72 . 0)
	    '(1 . "Test1 text")
	    '(7 . "TOM")
	    '(8 . "LAY02")
	    '(73 . 3))))
  (princ)
  )
0 Likes
Message 3 of 11

Kent1Cooper
Consultant
Consultant

@ВeekeeCZ wrote:

. If you have (could be omitted) some justification (as 73 or 72) you need to also have 11 with the same point as 10....


The DXF 10 and 11 locations don't need to be the same.  If the justification is not plain-old Left, that is, if you don't have both (72 . 0) and (73 . 0) entries, then the 11 value is the insertion point, and the 10 value is the left end of the base-line, and is only a result, relative to the insertion point, determined by the style, height, which particular non-Left justification, width factor & character content of the Text.  For some reason, you still need to give it a 10 value, but its coordinates will be ignored -- it will calculate its own.  It can be anything, such as '(10 0.0 0.0 0.0).

[If you change to Left justification, with the 72- and 73-code values both zero, you can give it a 10-code entry for the insertion point, and omit the 11-code entry.  You can give it one if you want, but it will likewise be ignored, and will always become (11 0.0 0.0 0.0).]

Kent Cooper, AIA
0 Likes
Message 4 of 11

audioGPQBX
Participant
Participant

BeeKeeCz,

 

You Rock. You Roll. I need to keep most all the justification options available. MR, ML, BR, BL, BC, etc. But NOT Aligned or Fit, we never use those. 

 

What you provided in your second post is perfect, well . . . . . almost perfect. I would like to do a table search for layer LAY02 as well as style TOM. If either one is missing, they get rejected.

 

I could get away with not checking for layer LAY02. Let EntMake create LAY02 and sneak in a layer  change color at the end of routine. This would force users to have their text strings on the correct layer and color.

 

I also have some historical verify style and layer routines I can adapt. So I am very happy that you solved my initial question.

0 Likes
Message 5 of 11

john.uhden
Mentor
Mentor

@audioGPQBX 

You are getting excellent guidance from @ВeekeeCZ and @Kent1Cooper.  They are two of the best here.

Here is some ancient code that may help you (if you can understand it).

You just have to provide the input arguments, which by inspection you should be able to figure out.

Don't mind all the | prefixes.  This comes from the days of old when localized variables weren't really localized at all, so I used the prefix to identify my own names and set them nil afterwards.  It handles the 72 and 73 codes if needed based on the justification you supply ("M" = Middle, "MC" = Middle Center, "MR" = Middle Right, "ML" = Middle Left).  I guess that's all I needed at the time.

Note that |style and |textstyle are intended to be a global within the program from which I took this.  If you have a problem with that you can always set |style to "Standard" before calling the function.  In fact you can get rid of  the | prefixes altogether.

   ;;-------------------------
   ;; Function to make DTEXT:
   ;;
   (defun @text (|str |p11 |ang |j |layer |color |height |wf |obl |style / |ent |j72 |j73 |p10 |tbox |boxw |boxh)
      (if (= |style "*Current*")
         (setq |style |textstyle)
      )
      (if (and (= (type |str) 'STR)(/= |str "")(not (wcmatch |str " ")))
         (progn
            (setq |ent
               (list '(0 . "TEXT") '(100 . "AcDbEntity")(cons 8 |layer)
                     '(100 . "AcDbText")(cons 40 |height) (cons 41 |wf)(cons 62 |color)
                     '(71 . 0) '(72 . 4) (cons 73 0) (cons 1 |str) (cons 7 |style)
                     '(50 . 0.0) (cons 51 |obl) '(210 0.0 0.0 1.0)
               )
                  |tbox (last (textbox |ent))
                  |boxw (nth 0 |tbox)
                  |boxh (nth 1 |tbox)
                  |p10 (polar |p11 (- |ang 1/2pi)(* |boxh 0.5))
            )
         ;   (princ "\n|boxw=")(prin1 |boxw)(princ "  |height=")(prin1 |height)
            (cond
               ((= |j "M")
                  (setq |j72 '(72 . 4)
                        |j73 '(73 . 0)
                        |p10 (polar |p10 (+ |ang pi) (* |boxw 0.5))
                  )
               )
               ((= |j "MC") ; figured out 9-06-99
                  (setq |p10 (polar |p11 (+ |ang pi)(/ |boxw 2))
                        |p10 (polar |p10 (- |ang 1/2pi)(/ |height 2))
                        |j72 '(72 . 1)
                        |j73 '(73 . 2)
                  )
               )
               ((= |j "MR") ; added 9-26-99
                  (setq |p10 (polar |p11 (+ |ang pi) |boxw)
                        |p10 (polar |p10 (- |ang 1/2pi)(/ |height 2))
                        |j72 '(72 . 2)
                        |j73 '(73 . 2)
                  )
               )
               (1  ; else ML
                  (setq |j72 '(72 . 0)
                        |j73 '(73 . 2)
                  )
               )
            )
            (setq |ent (@cv_subst (cons 50 |ang)(assoc 50 |ent) |ent))
            (setq |ent (@cv_subst |j72 (assoc 72 |ent) |ent))
            (setq |ent (@cv_subst |j73 (assoc 73 |ent) |ent))
            (setq |ent (append |ent (list (cons 10 |p10)(cons 11 |p11))))
            (entmake |ent)
         )
      )
   )

 

 

John F. Uhden

0 Likes
Message 6 of 11

Sea-Haven
Mentor
Mentor

Missing layers various methods of adding but start with 

(if (tblsearch "LAYER" lay) this returns True if exist if not then say make the layer.

 

(if (tblsearch "LAYER" lay)
(princ)
(command "-layer" "M" lay "")
)

 

0 Likes
Message 7 of 11

john.uhden
Mentor
Mentor

@Sea-Haven 

Good point, except entmake will create the named layer if it doesn't exist.

John F. Uhden

0 Likes
Message 8 of 11

ВeekeeCZ
Consultant
Consultant

@audioGPQBX wrote:

BeeKeeCz,

 

You Rock. You Roll. I need to keep most all the justification options available. MR, ML, BR, BL, BC, etc. But NOT Aligned or Fit, we never use those. 

>> Not sure why you note this. Are you wanting somehow add this to the routine? If so, why you don't simply use the (command "text") which offers these options...

 

What you provided in your second post is perfect, well . . . . . almost perfect. I would like to do a table search for layer LAY02 as well as style TOM. If either one is missing, they get rejected.

>> The list that is in the link I've posted also includes LAYER entmaking. And the LAYER test is similir to posted the STYLE test... search HELP you'll find how to cope with this yourself.

 

I could get away with not checking for layer LAY02. Let EntMake create LAY02 and sneak in a layer  change color at the end of routine. This would force users to have their text strings on the correct layer and color.

>> See the link that I've posted.

 

I also have some historical verify style and layer routines I can adapt. So I am very happy that you solved my initial question.

>> Glad to help.


 

0 Likes
Message 9 of 11

audioGPQBX
Participant
Participant

BeeKeeCz,

 

First off, thank  you for the assistance. I appreciate everything. You make very good points.

 

I think I got away from using the text command when I learned that the easiest way to make Mtext was with the EntMake.

 

As you can tell I am very much the lisp (or any other code language) neophyte. I am in over my head after three keystrokes in. 

 

Thanks to everybody's help and input.

0 Likes
Message 10 of 11

ВeekeeCZ
Consultant
Consultant
Accepted solution

Both methods have their pros and cons. The (command) is usually considered more suitable for newbies since it's generally known from the Autocad command-line. It's usually simpler. It has the fancy stuff included - dynamic previews. But it's not documented - it's like go to the command-line and watch - so things not obvious could be tricky. From time to time commands are changing between versions, routines have to be fixed then.

Entmake is more manual, usually more complicated, complex entities are not doable by entmake. But it's fast, the fastest method we have. And the structure is stable across versions.

 

(defun c:test1 (/ p)
  
  (if (and (or (tblsearch "STYLE" "TOM")
	       (alert "Error! 'TOM' Text style not defined in the drawing!"))
	   (or (tblsearch "LAYER" "LAY02")
	       (entmake (list '(0 . "LAYER") '(100 . "AcDbSymbolTableRecord") '(100 . "AcDbLayerTableRecord")
			      '(2 . "LAY02") '(70 . 0) '(62 . 1))))
	   (setq p (getpoint "\nPlace the text: "))
	   )
    (entmake (list '(0 . "TEXT")
		   (cons 10 p)
		   (cons 11 p)
		   '(40 . 0.1)
		   '(41 . 1.)
		   '(72 . 0)
		   '(1 . "Test1 text")
		   '(7 . "TOM")
		   '(8 . "LAY02")
		   '(73 . 3))))
  (princ)
  )

 

0 Likes
Message 11 of 11

john.uhden
Mentor
Mentor

@audioGPQBX 

She is sooooo good.

Be sure to hit that "Accept Solution" button at the bottom of HER RESPONSE, not this one.

Besides, by now you can probably type the entire word "defun."

Then you can work your way up to "vlax-curve-getclosestpointtoprojection."  🤗

John F. Uhden

0 Likes