Mtext break

Mtext break

kzD1219
Collaborator Collaborator
3,684 Views
12 Replies
Message 1 of 13

Mtext break

kzD1219
Collaborator
Collaborator

Are there any lisp routines that will break an piece of mtext into 2 pieces of mtext?

 

Say I have all one line of mtext with a bearing and a distance. I would like to break that in two and have both a bearing and separate piece of mtext.  I can use other things, but something like this would be the quickest.  Right now I am copying the mtext, editing it and well, I am sure there is something out there to just create two pieces of mtext (got to stay mtext).

 

The reason for this is sometimes I have the mtext spread out into one line and occasionally either only the bearing or the distance needs a background mask, not the entire spread out line of mtext.  So I would like to separate and then be able to manipulate just the one piece of mtext.

0 Likes
Accepted solutions (1)
3,685 Views
12 Replies
Replies (12)
Message 2 of 13

Kent1Cooper
Consultant
Consultant

There are routines you can Search for on these Forums for subdividing text strings around whatever delimiting character you want, in this case presumably a space.  So dividing the string content is achievable.  Is your intent to keep the resulting second-half piece visually in the same place?  That could be the more challenging part, and may not be doable with great precision, but could probably be done fairly close.

Kent Cooper, AIA
0 Likes
Message 3 of 13

kzD1219
Collaborator
Collaborator

Our bearings and distances are in a mtext string with 2 spaces between the 2 pieces of information.  Of course it would be nice to keep the two pieces close to their original position, but a little movement wouldn't matter much either.  That is what I am doing once I copy the mtext edit it anyways.  I was searching, but nothing caught my eye, just yet, but I will look some more.

0 Likes
Message 4 of 13

Kent1Cooper
Consultant
Consultant

@kzD1219 wrote:

....  I was searching, but nothing caught my eye, just yet, but I will look some more.


Here's a start.

Kent Cooper, AIA
0 Likes
Message 5 of 13

kzD1219
Collaborator
Collaborator

@Kent1Cooperwrote:

@kzD1219wrote:

....  I was searching, but nothing caught my eye, just yet, but I will look some more.


Here's a start.


Ah, great...thank you!  I will look at this.

0 Likes
Message 6 of 13

Kent1Cooper
Consultant
Consultant

Here's a beginning  of a routine, for your consideration:

(defun C:SM2 ; = Split Mtext into 2 pieces [around double space delimiter]
  (/ ss n mt mto1 txtinit mto2)
  (if (setq ss (ssget ":L" '((0 . "MTEXT"))))
    (repeat (setq n (sslength ss))
      (setq
        mt (ssname ss (setq n (1- n)))
        mto1 (vlax-ename->vla-object mt)
        txtinit (vla-get-TextString mto1)
        dsp (vl-string-search "  " txtinit); double space position
      ); setq
      (command "_.copy" mt "" '(0 0) "")
      (setq mto2 (vlax-ename->vla-object (entlast)))
      (vla-put-TextString mto1 (substr txtinit 1 dsp)); string before double space
      (vla-put-TextString mto2 (substr txtinit (+ dsp 3))); string after double space
      (vla-put-AttachmentPoint mto2 3); top-right justification
    ); repeat
  ); if
  (princ)
); defun

 

BUT note certain assumptions, limitations, etc.:

 

It assumes the original is top-left justified  in typical default fashion for Mtext, so if that might not always be the case, something would have to be done to accommodate different possibilities.

 

Given that justification, it copies it in place, then assigns top-right  justification to the copy that gets the second-half text content.  That uses the right end of the "defined width" of the Mtext "box," which may be wider [maybe a lot wider] than the actual content.  If so, the second-half piece will move more significantly.  If that's a meaningful issue, there are routines around that you can apply to pull the "defined width" of Mtext in to just the size of the actual content.

 

Speaking of defined width of the box, it assumes the initial content doesn't exceed that, i.e. there is no word wrapping based on that.  It "works" if there is, but the positioning can result in overlap of the two resulting pieces.

 

It assumes that there is, in fact, a double space somwhere in the text content, but could be made to check for that first.

 

And it doesn't have all the usual bells and whistles yet....

 

I'm playing with some possibilities to overcome some of those things, and may be back with improvements, but see what you think so far.

Kent Cooper, AIA
0 Likes
Message 7 of 13

kzD1219
Collaborator
Collaborator

WOW!  Kent, that is fantastic!  After it breaks in two, not many are going to notice the justification of the second piece of text.  The justification we most use is top, middle and bottom centre.

 

This is a great lisp routine for sure and so wish I had lisp routine writing talent.

 

If you do have time (and want) to add to this there is a few things that would make this work just as intended in my situation at least.  Keep the 2 pieces of mtext in the same position (and justification) after they are broken apart and removing any spaces that show up before the second piece of mtext. 

 

But this already creates less work, so thank you!

0 Likes
Message 8 of 13

Kent1Cooper
Consultant
Consultant

@kzD1219 wrote:

....  The justification we most use is top, middle and bottom centre. ....


Given that, try this adjustment, which relies on the original being one of those three justifications.  I found some good pieces of data to work with to eliminate [or at least minimize] the re-positioning, ignoring the "defined width" of the original's "box."

 

It results [in minimal testing] in quite-accurately-same-location pieces, and it respects the top/middle/bottom element  of the originals' justifications.  But  it leaves the left-end one from each justified to the left [Bottom Left if the original was Bottom Center, etc.] and the right one justified to the right.  With a little more work it could change the justifications to what the original was, and reposition so they don't appear to have moved [much], with some more extraction of character-set widths and calculation of new insertion points after it's done this much.  But see what you think of this, so far:

 

(defun C:SM2 ; = Split Mtext into 2 pieces
  (/ ss n mt mto1 txtinit inspt rot wid dsp mto2)
  (if (setq ss (ssget ":L" '((0 . "MTEXT"))))
    (repeat (setq n (sslength ss))
      (setq
        mt (ssname ss (setq n (1- n))); entity name [for Copy below]
        mto1 (vlax-ename->vla-object mt); as VLA object
        txtinit (vla-get-TextString mto1)
        inspt (vlax-get mto1 'InsertionPoint)
        rot (vla-get-rotation mto1)
        wid (cdr (assoc 42 (entget mt))); [not available as VLA property]
        dsp (vl-string-search "  " txtinit); double space position
      ); setq
      (command "_.copy" mt "" '(0 0) "")
      (setq mto2 (vlax-ename->vla-object (entlast)))
      (vla-put-AttachmentPoint mto1 (1- (vla-get-AttachmentPoint mto1))); left-end justification
      (vla-put-AttachmentPoint mto2 (1+ (vla-get-AttachmentPoint mto2))); right-end justification
      (vla-put-TextString mto1 (substr txtinit 1 dsp)); string before double space
      (vla-put-TextString mto2 (substr txtinit (+ dsp 3))); string after double space
      (vlax-put mto1 'insertionpoint (polar inspt (+ rot pi) (/ wid 2)))
      (vlax-put mto2 'insertionpoint (polar inspt rot (/ wid 2)))
    ); repeat
  ); if
  (princ)
); defun
(vl-load-com); just in case
Kent Cooper, AIA
0 Likes
Message 9 of 13

Kent1Cooper
Consultant
Consultant

@kzD1219 wrote:

.... removing any spaces that show up before the second piece of mtext.  ....


Does that imply that sometimes the separation is more than two  spaces?  The routines assume only two, but if it could be more, it wouldn't be hard to eliminate extras.

Kent Cooper, AIA
0 Likes
Message 10 of 13

kzD1219
Collaborator
Collaborator

@Kent1Cooperwrote:

@kzD1219wrote:

.... removing any spaces that show up before the second piece of mtext.  ....


Does that imply that sometimes the separation is more than two  spaces?  The routines assume only two, but if it could be more, it wouldn't be hard to eliminate extras.


Sorry, my bad.  No there won't be any more than 2 spaces.

0 Likes
Message 11 of 13

Kent1Cooper
Consultant
Consultant
Accepted solution

@Kent1Cooper wrote:

....  With a little more work it could change the justifications to what the original was, and reposition so they don't appear to have moved [much], with some more extraction of character-set widths and calculation of new insertion points after it's done this much. ....


Like this [it doesn't, in the end change the justification and then change it back, but leaves it alone and calculates a new insertion point]:

(defun C:SM2 ; = Split Mtext into 2 pieces
;; starting from top-/middle-/bottom-CENTER justifications,
;; split around two-spaces separators
  (/ ss n mt mto1 txtinit inspt rot wid dsp mto2 wid1 wid2)
  (if (setq ss (ssget ":L" '((0 . "MTEXT"))))
    (repeat (setq n (sslength ss))
      (setq
        mt (ssname ss (setq n (1- n))); entity name [for Copy below]
        mto1 (vlax-ename->vla-object mt); as VLA object
        txtinit (vla-get-TextString mto1)
        inspt (vlax-get mto1 'InsertionPoint)
        rot (vla-get-rotation mto1)
        wid (cdr (assoc 42 (entget mt))); [not available as VLA property]
        dsp (vl-string-search "  " txtinit); double space position
      ); setq
      (command "_.copy" mt "" '(0 0) "")
      (setq mto2 (vlax-ename->vla-object (entlast)))
      (vla-put-TextString mto1 (substr txtinit 1 dsp)); string before double space
      (vla-put-TextString mto2 (substr txtinit (+ dsp 3))); string after double space
      (redraw mt); needed to get reduced widths correctly [otherwise uses original]
      (redraw (entlast)); likewise
      (setq
        wid1 (cdr (assoc 42 (entget mt))); reduced width of original
        wid2 (cdr (assoc 42 (entget (entlast)))); width of after-spaces piece
      ); setq
      (vlax-put mto1 'insertionpoint (polar inspt (+ rot pi) (/ (- wid wid1) 2)))
      (vlax-put mto2 'insertionpoint (polar inspt rot (/ (- wid wid2) 2)))
    ); repeat
  ); if
  (princ)
); defun

Could still use the other typical stuff [*error* handling, command-echo suppression, Undo begin/end, etc.].
Kent Cooper, AIA
Message 12 of 13

kzD1219
Collaborator
Collaborator

@Kent1Cooperwrote:

@Kent1Cooperwrote:

....  With a little more work it could change the justifications to what the original was, and reposition so they don't appear to have moved [much], with some more extraction of character-set widths and calculation of new insertion points after it's done this much. ....


Like this [it doesn't, in the end change the justification and then change it back, but leaves it alone and calculates a new insertion point]:

(defun C:SM2 ; = Split Mtext into 2 pieces
;; starting from top-/middle-/bottom-CENTER justifications,
;; split around two-spaces separators
  (/ ss n mt mto1 txtinit inspt rot wid dsp mto2 wid1 wid2)
  (if (setq ss (ssget ":L" '((0 . "MTEXT"))))
    (repeat (setq n (sslength ss))
      (setq
        mt (ssname ss (setq n (1- n))); entity name [for Copy below]
        mto1 (vlax-ename->vla-object mt); as VLA object
        txtinit (vla-get-TextString mto1)
        inspt (vlax-get mto1 'InsertionPoint)
        rot (vla-get-rotation mto1)
        wid (cdr (assoc 42 (entget mt))); [not available as VLA property]
        dsp (vl-string-search "  " txtinit); double space position
      ); setq
      (command "_.copy" mt "" '(0 0) "")
      (setq mto2 (vlax-ename->vla-object (entlast)))
      (vla-put-TextString mto1 (substr txtinit 1 dsp)); string before double space
      (vla-put-TextString mto2 (substr txtinit (+ dsp 3))); string after double space
      (redraw mt); needed to get reduced widths correctly [otherwise uses original]
      (redraw (entlast)); likewise
      (setq
        wid1 (cdr (assoc 42 (entget mt))); reduced width of original
        wid2 (cdr (assoc 42 (entget (entlast)))); width of after-spaces piece
      ); setq
      (vlax-put mto1 'insertionpoint (polar inspt (+ rot pi) (/ (- wid wid1) 2)))
      (vlax-put mto2 'insertionpoint (polar inspt rot (/ (- wid wid2) 2)))
    ); repeat
  ); if
  (princ)
); defun

Could still use the other typical stuff [*error* handling, command-echo suppression, Undo begin/end, etc.].

This is great stuff!  Thanks so much for your time and effort!  

0 Likes
Message 13 of 13

Anonymous
Not applicable

If you have a long MTEXT that will not fit in one sheet, follow below steps:

 

1. make your Mtext into 2 columns: right click inside Mtex >> Columns >> Insert Column Break form the point that you want to break your Mtext

 

2. Explode the entire Mtex and you will have 2 columns of Mtext that are separated.

0 Likes