View Full Version : Creating Text Objects via LISP
margaretl
2007-04-19, 07:15 PM
I have the following, so far. - see attached.
I am new to LISP and have used the forum to answer many questions in creating this routine. However, I cannot locate anything about having the lisp routine generate text from scratch.
Everything works well except the text passes in the command line before the prompt and then I am prompted to enter the text.
1.) How do I get my text to fill in at the prompt on its own?
2.) How would I go about getting the rotation angle by picking a line, arc, or polyline segment? In this particular routine, I want my text parallel to the selected line at the insertion point selected by the user. (I know there is no snap for parallel to an arc, but it can be done manually.)
After I get this to work, I want to generate an additional routine that will make the text perpendicular to the selected line, arc, or polyline segment with the insertion a specified distance away.
Please go easy on me. I am trying to adsorb as much of this as possible for future use. Explanations of what was done any why would be greatly appreciated.
Use text instead of dtext command
Give that a try
;routine to add easement text without typing
; Convert value in radians to degrees
(defun rtd (a)
(* 180.0 (/ a pi))
)
(defun c:pude (/ ssPoint ssAngle strPude oldLay oldStyle)
;obtain current settings
(setq OldLay (getvar "CLayer"))
(setq oldStyle (getvar "textstyle"))
(setq oldOsm (getvar "osmode"))
;check for easements layer and create if missing
(if (= (tblsearch "layer" "Easements") nil)
(command "layer" "make" "Easements" "color" "4" "" "lt" "dashed2" "" ""))
(setvar "CLayer" "Easements")
;check for L80 textstyle and create if missing
(if (= (tblobjname "textstyle" "L80") nil)
(command "-style" "L80" "simplex.shx" "1.6" "" "14" "" "" ""))
(setvar "textstyle" "L80")
;pick insertion point and rotation for text
(setq ssPoint (getpoint "\nSelect insertion point of text: "))
(setq ssAngle (getangle ssPoint "\nSelect rotation of text: "))
;fill in text
(setq strPude (getstring T "\nPublic Utilities & Drainage Easement: "))
(setvar "osmode" 0)
(command "text" "j" "mc" ssPoint (rtd ssAngle) strPude)
;reset to original settings
(setvar "CLayer" oldLay)
(setvar "textstyle" oldStyle)
(setvar "osmode" oldOsm)
(princ)
)
~'J'~
CAB2k
2007-04-19, 10:41 PM
Here is one way.
;;; ARGUMENTS
;;; txt = the text string
;;;
;;; USAGE
;;; text_edit
;;;
;;; PLATFORMS
;;; 2000+
;;;
;;; AUTHOR
;;; Charles Alan Butler
;;;
;;; VERSION
;;; 1.0 Oct. 06, 2004
(defun text_edit (txt / entlist ent)
(if (entmake
(list
'(0 . "TEXT")
(cons 10 '(0 0))
(cons 40 1)
(cons 7 (getvar "TEXTSTYLE"))
(cons 1 txt) ; Text String
)
)
(progn
(setq ent (entlast))
(command "._ddedit" ent "")
(setq txt (cdr (assoc 1 (entget ent))))
(entdel ent)
txt
)
)
)
(defun c:test (/ newtext)
(setq newtext (text_edit "This is a test string."))
)
jwanstaett
2007-04-20, 01:21 PM
I have the following, so far. - see attached.
(I know there is no snap for parallel to an arc, but it can be done manually.)
snap to the center of the arc
margaretl
2007-04-20, 01:50 PM
Thanks to all who replied. This is very helpful.
Fixo:
I see you added in the rotation and converted radians to degrees, could you explain how this works in layman's terms?
Also, with filling in the text, why text instead of DText and what does T do?
I ran the routine. Now at the command line instead of Enter text: is says Public Utilities & Drainage Easement: as a prompt for enter text. This will work for what I want if there is a way to make the default text "Public Utilities & Drainage Easement".
CAB2k:
I am totally lost trying to follow what you did. If you care to explain, I would gladly listen.
I tried to run the routine. I could not find what to type at the command line. I ran the sub routine, test and came up with a DText editor that said This is a test string. I tried txt and text_edit. I, also, tried to modify the defun text_edit to c:defun text_edit and received the error too few arguments.
jwanstaett:
Snapping to the center would result in a perpendicular piece of text. Therefore, to get the parallel/concentric look I need, I would have to rotate the text, also. Therefore, no parallel snap for an arc. All done manually.
Hi Margaret
I changed one line of listing only, see commented line
;routine to add easement text without typing
; Convert value in radians to degrees
(defun rtd (a)
(* 180.0 (/ a pi))
)
(defun c:pude (/ ssPoint ssAngle strPude oldLay oldStyle)
;obtain current settings
(setq OldLay (getvar "CLayer"))
(setq oldStyle (getvar "textstyle"))
;check for easements layer and create if missing
(if (= (tblsearch "layer" "Easements") nil)
(command "layer" "make" "Easements" "color" "4" "" "lt" "dashed2" "" ""))
(setvar "CLayer" "Easements")
;check for L80 textstyle and create if missing
(if (= (tblobjname "textstyle" "L80") nil)
(command "-style" "L80" "simplex.shx" "1.6" "" "14" "" "" ""))
(setvar "textstyle" "L80")
;pick insertion point and rotation for text
(setq ssPoint (getpoint "\nSelect insertion point of text: "))
(setq ssAngle (getangle ssPoint "\nSelect rotation of text: "))
;fill in text
(setq strPude "Public Utilities & Drainage Easement");<--***getstring removed***
(command "text" "j" "mc" ssPoint (rtd ssAngle) strPude)
;reset to original settings
(setvar "CLayer" oldLay)
(setvar "textstyle" oldStyle)
(princ)
)
About your question:
T symbol in GETSTRING function allows for you
to input string include spaces (blanks)
If you need to pass the certain string as default,
there are few ways to do it
One of those like this one:
(setq strPude (getstring T "\nEnter the string <Public Utilities & Drainage Easement>: "))
then if Enter pressed this will return an empty string
if so you can to check it:
(if (eq "" ;|<--empty|; strPude);<-- compare an input, then
(setq strPude "Public Utilities & Drainage Easement")
)
in this case you will to get the default string
that was written in angular brackets
Another way to use GETKWORD function,
see Help about, please
English is very difficult for me :)
Just a quick example:
(initget 1 "Alpha Bravo Charlie Delta");<-- 1 is disallows null input
(setq return (getkword "\Type something here (A/B/C/D) <A> : "))
if you type any of characters that appears in brackets
this will return the whole word
if Enter pressed the function will return 'nil'
(ugly English isn't it?)
~'J'~
margaretl
2007-04-20, 04:10 PM
You don't give yourself enough credit with your English. I was able to follow that no problem.
Thank you very much with your assistance. This routine and several similar routines will same me time and typing.
You are welcome
Cheers :)
~'J'~
CAB2k
2007-04-20, 11:22 PM
margaretl
Using Fixo's example & combining it with my routine.
See example below.
;routine to add easement text without typing
; Convert value in radians to degrees
(defun rtd (a)
(* 180.0 (/ a pi))
)
(defun c:pude (/ ssPoint ssAngle strPude oldLay oldStyle)
;obtain current settings
(setq OldLay (getvar "CLayer"))
(setq oldStyle (getvar "textstyle"))
;check for easements layer and create if missing
(if (= (tblsearch "layer" "Easements") nil)
(command "layer" "make" "Easements" "color" "4" "" "lt" "dashed2" "" ""))
(setvar "CLayer" "Easements")
;check for L80 textstyle and create if missing
(if (= (tblobjname "textstyle" "L80") nil)
(command "-style" "L80" "simplex.shx" "1.6" "" "14" "" "" ""))
(setvar "textstyle" "L80")
;pick insertion point and rotation for text
(setq ssPoint (getpoint "nSelect insertion point of text: "))
(setq ssAngle (getangle ssPoint "nSelect rotation of text: "))
;fill in text
(setq strPude (text_edit "Public Utilities & Drainage Easement"))
(command "text" "j" "mc" ssPoint (rtd ssAngle) strPude)
;reset to original settings
(setvar "CLayer" oldLay)
(setvar "textstyle" oldStyle)
(princ)
)
;;; ARGUMENTS
;;; txt = the text string
;;;
;;; USAGE
;;; text_edit
;;;
;;; PLATFORMS
;;; 2000+
;;;
;;; AUTHOR
;;; Charles Alan Butler
;;;
;;; VERSION
;;; 1.0 Oct. 06, 2004
(defun text_edit (txt / entlist ent)
(if (entmake
(list
'(0 . "TEXT")
(cons 10 '(0 0))
(cons 40 1)
(cons 7 (getvar "TEXTSTYLE"))
(cons 1 txt) ; Text String
)
)
(progn
(setq ent (entlast))
(command "._ddedit" ent "")
(setq txt (cdr (assoc 1 (entget ent))))
(entdel ent)
txt
)
)
)
margaretl
2007-11-05, 04:34 PM
I have attached the final code I have been using. This code is in about 5 different routines now. I like how it works with one exception. The different routines I am using have different text heights. The routine is now exiting cleanly and the next routine is retaining the text height instead of generating its own.
Any suggestions?
CAB2k
2007-11-05, 05:28 PM
It appears as though it should set the text height.
Although variable ssHeight is undefined & not needed.
Subroutine (defun Hgt (b) does not use the argument 'b', why have it?
(command "text" "j" "mc"
"_non" ssPoint ; prevent osnaps
(* (getvar "dimscale") 0.08)
(rtd ssAngle)
strPude)
When you say the next routine is retaining the text height, remember that when a style height is set to
zero the TEXTSIZE is updated each time a text command is executed. So you must not use "" as a
response to the text size if you want a specific size.
Command: text
Current text style: "Standard" Text height: 0'-5"
Specify start point of text or [Justify/Style]:
Specify height <0'-5">: 3
Specify rotation angle of text <0.0000>:
Enter text: This is 3" text height
Enter text:
Command: text
Current text style: "Standard" Text height: 0'-3"
Specify start point of text or [Justify/Style]:
Specify height <0'-3">: <----<< if you use ""
Specify rotation angle of text <0.0000>:
Enter text: This will remain 3" height
Enter text:
margaretl
2007-11-08, 03:24 PM
I understand what you were saying with the fixed text height in the text style. I do not want to do this because this lisp needs to set the height of the text based on the scale of the drawing I am in. I also understand why ssHeight isn't needed. I removed (b) as the argument and took out ssHeight.
I have a similar routine that places a lot number. It asks for the insertion point and the rotation, then user inputs the number. The routine sets the text height (bigger than the PUDE routine), the layer, color, style, etc.
The problem is the Hgt routine is not resetting because Hgt has a value from the previous routine.
Each routine runs fine if I load it then run it. It continues to run fine. The routine that gets loaded second takes over Hgt. I need to switch back and forth between the routines without having to load them each time.
I have attached the Lnum routine so you can get a better idea of what I am talking about.
margaretl
2007-11-08, 03:57 PM
I figured something out.
Hgt is a subroutine in the LISP and is only being loaded once per a session. Because of this, I cannot expect Hgt to give me different answers each time. What I did to get around this, I set up different subroutines for each text height (Hgt08 Hgt09 Hgt10).
This works even if the scale of my drawing changes.
Also, I am not sure why, but after taking out the (b) argument and the ssHeight the routine stopped working. I was getting sytax error on the command line when the routine loaded.
CAB2k
2007-11-08, 04:17 PM
This sub should be included with each routine or loaded first by your ACADdoc.lsp.
Note that I changed the routine.
; Calculate Text Height
(defun Hgt (b)
(/ (getvar "dimscale") b)
)
So you need to change each call to this routine like this,
Change this line:
(command "text" "j" "mc" ssPoint (Hgt ssHeight) (rtd ssAngle) strLot)
To this
(command "text" "j" "mc" ssPoint (Hgt 5) (rtd ssAngle) strLot)
But use the proper dimScale divider.
margaretl
2007-11-08, 07:13 PM
Thanks for you help. This will save me quite a few steps and a lot of typing.
Powered by vBulletin® Version 4.2.5 Copyright © 2025 vBulletin Solutions Inc. All rights reserved.