Jump to content

Replace text with predefined text


OMEGA-ThundeR

Recommended Posts

Hi,

 

I could find some find and replace-ish lisp routines, but not something i am looking for.

 

I type a lot of objectdescription, and for 8/10 drawings the description is mostly the same, but the way it is presented is usually different.

I could copy/past from some textfile or previous text withing the drawing, but i think that can be done faster.

 

I'm looking for a function that would replace a selected text (mtext or regular text) with something predefined in a lisp.

Lets say:

 

(defun c:replace1 (/ text selecttext)

(setq text "this is a description text")

(setq selecttext (ssget "_:L" '((0 . "MTEXT,TEXT"))))

 

*Part of the code that changes out the predifined text with the selected text/mtext*

 

Shouldn't be so hard right? :P

 

 

Link to comment
Share on other sites

2 hours ago, OMEGA-ThundeR said:

Hi,

Shouldn't be so hard right? :P

 

No its not. 😉

(defun c:replace1 (/ text sel int)

  (setq text "this is a description text")

  (if (setq sel (ssget "_:L" '((0 . "MTEXT,TEXT"))))
    (repeat (setq int (sslength sel))
      (entmod (append (entget (ssname sel (setq int (1- int))))
                      (list (cons 1 text))
              )
      )
    )
  )
  (princ)
)

 

  • Like 1
Link to comment
Share on other sites

@Tharwat

FWIW, I'd use vla-put-textstring. Large mtext strings are broken up into multiple 3 codes so entmodding 1 is unreliable. 

Quote

_$ 
((-1 . <Entity name: 21985c54a50>)
  (0 . "MTEXT")
  (330 . <Entity name: 2199b10f2d0>)
  (5 . "102509D")
  (100 . "AcDbEntity")
  (67 . 1)
  (410 . "004")
  (8 . "0")
  (100 . "AcDbMText")
  (10 434.871 344.729 0.0)
  (40 . 2.5)
  (41 . 80.01)
  (46 . 0.0)
  (71 . 1)
  (72 . 1)
  (3
    .
    "The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. \\PThe quick brown fox jumps over the lazy dog. \\PThe quick brown fox jumps over the lazy dog. \\PThe quick brown fox jumps over the lazy dog. \\PThe quick brown f"
  )
  (3
    .
    "ox jumps over the lazy dog. \\PThe quick brown fox jumps over the lazy dog. \\PThe quick brown fox jumps over the lazy dog. \\PThe quick brown fox jumps over the lazy dog. \\PThe quick brown fox jumps over the lazy dog. \\PThe quick brown fox jumps over t"
  )
  (3
    .
    "he lazy dog. \\PThe quick brown fox jumps over the lazy dog. \\PThe quick brown fox jumps over the lazy dog. \\PThe quick brown fox jumps over the lazy dog. \\PThe quick brown fox jumps over the lazy dog. \\PThe quick brown fox jumps over the lazy dog. \\P"
  )
  (3
    .
    "The quick brown fox jumps over the lazy dog. \\PThe quick brown fox jumps over the lazy dog. \\PThe quick brown fox jumps over the lazy dog. \\PThe quick brown fox jumps over the lazy dog. \\PThe quick brown fox jumps over the lazy dog. \\PThe quick brown"
  )
  (1
    .
    " fox jumps over the lazy dog. \\PThe quick brown fox jumps over the lazy dog. \\PThe quick brown fox jumps over the lazy dog. "
  )
  (7 . "Standard")
  (210 0.0 0.0 1.0)
  (11 1.0 0.0 0.0)
  (42 . 77.8)
  (43 . 99.0833)
  (50 . 0.0)
  (73 . 1)
  (44 . 1.0)
)
_$ 

 

  • Thanks 2
Link to comment
Share on other sites

1 hour ago, OMEGA-ThundeR said:

Works like a charm! Thanks!

You're welcome. :)

 

@ronjonp 

Yeah, you are right and I am honestly aware of that but the OP asks for something very simple faraway enough from the DXF group 3.

Brave fox by the way. 😉

  • Like 1
Link to comment
Share on other sites

15 minutes ago, Tharwat said:

You're welcome. :)

Minor setback, it changes it normal TEXT objects, but it ads the text with mtext objects.  The original content isn't removed from mtext.

Is that what that 'DXF group 3' is about?

My mtext lines are not long, and even single words mtext objects don't get replaced.

Link to comment
Share on other sites

6 minutes ago, OMEGA-ThundeR said:

Minor setback, it changes it normal TEXT objects, but it ads the text with mtext objects.  The original content isn't removed from mtext.

Is that what that 'DXF group 3' is about?

My mtext lines are not long, and even single words mtext objects don't get replaced.

You can try instead. :)

(defun c:replace1 (/ text sel int)

  (setq text "this is a description text")

  (if (setq sel (ssget "_:L" '((0 . "MTEXT,TEXT"))))
    (repeat (setq int (sslength sel))
      (setq e (entget (ssname sel (setq int (1- int)))))
      (entmod (subst (cons 1 text) (assoc 1 e) e))
    )
  )
  (princ)
)

DXF Group Code 3 is about Text string that exceed more than 250 chars if I am not mistaken so read THIS for more info.

  • Like 1
Link to comment
Share on other sites

  • 4 years later...

Hi Tharwat, great lisp! I use this everyday!

 

Is it possible to modify this to replace only the LAST 4 chars?

Or, is it possible to have the option to change only the FIRST 3 chars?

 

Thank you.

Edited by barristann
Link to comment
Share on other sites

If I have a TEXT or MTEXT:

                ABC-1234

 

a. I would like to replace the LAST 4 chars with for example 6789

                ABC-6789

 

b. or I would like to replace the FIRST 3 chars with for example XYZ

               XYZ-1234

Edited by barristann
Link to comment
Share on other sites

This is to replace the end chars of selected texts.

NOTE: Be sure to have your selected Mtexts objects unformatted.

 

(defun c:Test ( / str len int sel ent get txt lng )
  ;;----------------------------------------------------;;
  ;;	Author : Tharwat Al Choufi			;;
  ;; website: https://autolispprograms.wordpress.com	;;
  ;;----------------------------------------------------;;
  (setq str "6789"
        len (strlen str)
        )
  (and (princ (strcat "\nSelect text to replace the end chars with < " str " > : "))
       (setq int -1 sel (ssget "_:L" '((0 . "TEXT,MTEXT"))))
       (while (setq int (1+ int) ent (ssname sel int))
         (setq get (entget ent)
               txt (assoc 1 get)
               )
         (and (<= len (setq lng (strlen (cdr txt))))
              (entmod (subst (cons 1 (strcat (substr (cdr txt) 1 (- lng len)) str)) txt get))
              )
         )
       )
  (princ)
  )

 

  • Like 1
Link to comment
Share on other sites

Here is another routine for the second one although the mods are a little, so hopefully you can learn something from these posted two routines. :)

 

(defun c:Test ( / str len int sel ent get txt lng )
  ;;----------------------------------------------------;;
  ;;	Author : Tharwat Al Choufi			;;
  ;; website: https://autolispprograms.wordpress.com	;;
  ;;----------------------------------------------------;;
  (setq str "XYZ"
        len (strlen str)
        )
  (and (princ (strcat "\nSelect text to replace the end chars with < " str " > : "))
       (setq int -1 sel (ssget "_:L" '((0 . "TEXT,MTEXT"))))
       (while (setq int (1+ int) ent (ssname sel int))
         (setq get (entget ent)
               txt (assoc 1 get)
               )
         (and (<= len (setq lng (strlen (cdr txt))))
              (entmod (subst (cons 1 (strcat str (substr (cdr txt) 1 len))) txt get))
              )
         )
       )
  (princ)
  )

 

  • Like 1
Link to comment
Share on other sites

Great Tharwat. They both work!

I'm very curious, it is possible to use the "-" character to indicate where to stop replacing?

 

If I have many TEXT or MTEXT:   

                AB-12

                ABC-123

                ABCDE-123456  

 

a. I would like to replace All the chars on the RIGHT of "-" with 678

               AB-678

               ABC-678

               ABCDE-678

 

b. or I would like to replace All the Chars on the Left of  "-" with XYZ

               XYZ-12

               XYZ-123

               XYZ-123456

 

Thank you Tharwat

 

 

 

 

 

 

 

 

 

 

 

 

 

Edited by barristann
Link to comment
Share on other sites

So you could look into this page here:

https://help.autodesk.com/view/OARX/2023/ENU/?guid=GUID-8543549B-F0D7-43CD-87A3-F6B827FF0B88

which gives the string functions. Perhaps use:

(strlen [string ...]) to find the length of the text string

(vl-string-search pattern string [ start-pos]) to find the position of the first '-' and from calculate the variable 'len' in the code above and go from there.

 

 

As an alternative I use Lee Macs String to List (http://lee-mac.com/stringtolist.html#:~:text=%3B%3B String to List - Lee Mac %3B%3B,str (%2B pos len)))) (reverse (cons str lst)))) to split the text strings into parts, then remake the string using the parts and changing them as required. I quite like this way since you can change any part of the text between any deliminators - even multiple changes easily.

 

Something like this: Should be quite versatile to do all the above, variable lengths, suffix and prefix, 

(defun c:Testthis ( / Prefix Suffix presuf ss acount MyNewString MyEnt MyString MyList MyCount MyNewString)

(setq Prefix "Prefix TExt") ; change these texts as required or
;;(setq Prefix (getstring T "\nEnter Prefix Text:"))
(setq Suffix "Suffix Text")
;;(setq Suffix (getstring T "\nEnter Suffix Text:"))


;;Sub Functions
  (defun LM:str->lst ( str del / pos )
    (if (setq pos (vl-string-search del str))
        (cons (substr str 1 pos) (LM:str->lst (substr str (+ pos 1 (strlen del))) del))
        (list str)
    )
  )

  (initget "pre suf both")
  (setq presuf (strcase (getkword "\nEnter an option (Pre/Suf/both): ") )) ; Select change to make

  (setq ss (ssget '((0 . "*TEXT"))) ) ; Select text, mtext, rtext
  (setq acount 0)
  (while (< acount (sslength ss)) ; loop through selection
    (setq MyNewString "") ; empty text string
    (setq MyEnt (entget (ssname ss acount)) )
    (setq MyString (cdr (assoc 1 MyEnt))) ; Gets text strinbg (up to 1st ~500 characters)
    (setq MyList (LM:str->lst MyString "-")) ; text to list

;;Modify list items, could use cond here
    (if (= presuf "PRE") (setq MyList (subst Prefix (nth 0 MyList) MyList ) ) )
    (if (= presuf "SUF") (setq MyList (subst Suffix (nth 0 (reverse MyList)) MyList ) ) )
    (if (= presuf "BOTH")
      (progn
        (setq MyList (subst Prefix (nth 0 MyList) MyList ) ) ; Change Prefix text as you want
        (setq MyList (subst Suffix (nth 0 (reverse MyList)) MyList ) ) ; change Suffix text as you want
      )
    )

;;Remake text from list
    (setq MyNewString (nth 0 MyList))
    (setq MyCount 1)
    (while (< MyCount (length MyList))
      (setq MyNewString (strcat MyNewString "-" (nth MyCount MyList)))
      (setq MyCount (+ MyCount 1))
    ) ; end while
    (entmod (subst (cons 1 MyNewString) (assoc 1 MyEnt) MyEnt )) ; update text
    (setq acount (+ acount 1))
  ) ; end while
  (princ)
)

 

Edited by Steven P
EDIT: Added 'getstring' for the suffix and prefix
  • Like 1
Link to comment
Share on other sites

(sorry Tharwat - 20 minutes copy, paste and check isn't going to pay enough to cover your time to even make an invoice in this case)

  • Like 1
Link to comment
Share on other sites

That's 100% incredible, Steven! I used your codes so many times at work today. I was speechless when I first tested them this morning. I'm still amazed something like this can be coded. Thank you Steven P for being so awesome!

  • Like 1
Link to comment
Share on other sites

That's no problem, it was all copy and pasted from other things.

 

I have updated the code slightly so that the prefix and suffix text is at the start (easier to find and change when it is there), but also commented out 2 lines containing 'getstring' - remove the ; and the LISP will ask the for user input for the text to add

  • Like 1
Link to comment
Share on other sites

Wow it was already great, but you've made it even better, Steven. I'll study your codes for sure. Thank you for going above and beyond, Steven!

Edited by barristann
  • Like 1
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...