Author Topic: {Challenge}Get the textstrings in each line of the mtext  (Read 12107 times)

0 Members and 1 Guest are viewing this topic.

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: {Challenge}Get the textstrings in each line of the mtext
« Reply #15 on: March 09, 2013, 01:26:15 AM »
It seems like only explode command can do that thing.
I seem to remember that MText actually stores the portions as DText inside an anonymous block definition. But for the love of Pete ... I can't seem to find this. Perhaps I was thinking of something else  ::)
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

xiaxiang

  • Guest
Re: {Challenge}Get the textstrings in each line of the mtext
« Reply #16 on: March 09, 2013, 02:05:43 AM »
It seems like only explode command can do that thing.
I seem to remember that MText actually stores the portions as DText inside an anonymous block definition. But for the love of Pete ... I can't seem to find this. Perhaps I was thinking of something else  ::)
Really nice! As far as I've know the textstring of Mtext is stored as one combination.Any further information is welcome.
Xia

fervour

  • Guest
Re: {Challenge}Get the textstrings in each line of the mtext
« Reply #17 on: January 06, 2015, 05:13:22 PM »
I have a sentence in mtext and all the words are separated with TAB spacer. What is the modification to make so that it only breaks the tabs between words and not regular spaces.

Thank you.

alanjt

  • Needs a day job
  • Posts: 5352
  • Standby for witty remark...
Re: {Challenge}Get the textstrings in each line of the mtext
« Reply #18 on: January 07, 2015, 12:02:06 AM »
I have a sentence in mtext and all the words are separated with TAB spacer. What is the modification to make so that it only breaks the tabs between words and not regular spaces.

Thank you.
Lee's code should do the trick, just edit the _splitwords fuction to include tabs.

*untested*
Code: [Select]
    (defun _splitwords ( str / pos )
        (if (setq pos (vl-string-position 9 str)) ;alanjt edit 32 to 9 (search for tab instead of space
            (cons (cons 1 (substr str 1 pos)) (_splitwords (substr str (+ pos 2))))
            (list (cons 1 str))
        )
    )
Civil 3D 2019 ~ Windohz 7 64bit
Dropbox

Lee Mac

  • Seagull
  • Posts: 12913
  • London, England
Re: {Challenge}Get the textstrings in each line of the mtext
« Reply #19 on: January 07, 2015, 04:10:20 AM »
Thanks Alan -

Since the difference between the total text width and the sum of the width of each word is divided equally between the words, then providing all of the words are separated by tabs, the modification should work. Obviously, if one has a combination of spaces & tabs, the new text items will be spaced using an average of the space between each of the original words.

Lee

fervour

  • Guest
Re: {Challenge}Get the textstrings in each line of the mtext
« Reply #20 on: January 07, 2015, 11:30:56 AM »
Thanks for the suggestion.

I tried, but the code only look after Dtext, and the Tab delimiter turns into space after being converted from mtext to dtext.
I have a single mtext entity with 2 lines for example:

1st line of mtext: Today[Tab]is[space]a[space]great[tab]day
2nd line of mtext: Tomorrow[Tab]will[space]also[space]be[space]a[space]great[tab]day

I am hoping to break the above by looking at [tab] only.
So the above result will convert 1 mtext to 6 dtext or 6 mtext:

Today
is a great
day
Tomorrow
will also be a a great
day

(no need to be in separate new lines like above, I just showed like as an example).

Thanks again  :-)

ronjonp

  • Needs a day job
  • Posts: 7527
Re: {Challenge}Get the textstrings in each line of the mtext
« Reply #21 on: January 07, 2015, 11:41:44 AM »
This works for me:
Code - Auto/Visual Lisp: [Select]
  1. (defun _splitwords (str del / pos)
  2.   ;; RJP mod vl-string-search for readability and delimiter argument
  3.   (if (setq pos (vl-string-search del str))
  4.     (cons (substr str 1 pos) (_splitwords (substr str (+ pos (1+ (strlen del))))del))
  5.     (list str)
  6.   )
  7. )
  8. (setq str (vla-get-textstring (vlax-ename->vla-object (car (entsel)))))
  9. (_splitwords str "\t")
  10.  
  11.  
  12. ;; "Tomorrow\twill also be a great\tday"
  13. ;; Returns
  14. ;; ("Tomorrow" "will also be a great" "day")
« Last Edit: January 07, 2015, 12:10:14 PM by ronjonp »

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

alanjt

  • Needs a day job
  • Posts: 5352
  • Standby for witty remark...
Re: {Challenge}Get the textstrings in each line of the mtext
« Reply #22 on: January 07, 2015, 12:00:16 PM »
This works for me:
Code - Auto/Visual Lisp: [Select]
  1. (defun _splitwords (str del / pos)
  2.   ;; RJP mod vl-string-search for readability and delimiter argument
  3.   (if (setq pos (vl-string-search del str))
  4.     (cons (substr str 1 pos) (_splitwords (substr str (+ pos 2))del))
  5.     (list str)
  6.   )
  7. )
  8. (setq str (vla-get-textstring (vlax-ename->vla-object (car (entsel)))))
  9. (_splitwords str "\t")
  10.  
  11.  
  12. ;; "Tomorrow\twill also be a great\tday"
  13. ;; Returns
  14. ;; ("Tomorrow" "will also be a great" "day")
Be aware that the +2 would fail to yield desired results if the delimiter exceeded the intended single digit.

eg.
Code: [Select]
Command: (_splitwords "i_-_love_-_pizza" "_-_")
("i" "-_love" "-_pizza")

This is pointless in this situation, and a simple strlen would fix the issue, but I just thought it was worth mentioning.
Civil 3D 2019 ~ Windohz 7 64bit
Dropbox

ronjonp

  • Needs a day job
  • Posts: 7527
Re: {Challenge}Get the textstrings in each line of the mtext
« Reply #23 on: January 07, 2015, 12:05:10 PM »
Ah yes :) thanks Alan .. I'll modify above.

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

alanjt

  • Needs a day job
  • Posts: 5352
  • Standby for witty remark...
Re: {Challenge}Get the textstrings in each line of the mtext
« Reply #24 on: January 07, 2015, 12:09:23 PM »
Ah yes :) thanks Alan .. I'll modify above.
:) I was mainly just looking for an excuse to express admiration for my one true love.
Civil 3D 2019 ~ Windohz 7 64bit
Dropbox

fervour

  • Guest
Re: {Challenge}Get the textstrings in each line of the mtext
« Reply #25 on: January 07, 2015, 12:49:17 PM »
The lisp won't let me select Mtext though...?

ronjonp

  • Needs a day job
  • Posts: 7527
Re: {Challenge}Get the textstrings in each line of the mtext
« Reply #26 on: January 07, 2015, 01:04:50 PM »
The lisp won't let me select Mtext though...?


Sure it does.

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

ronjonp

  • Needs a day job
  • Posts: 7527
Re: {Challenge}Get the textstrings in each line of the mtext
« Reply #27 on: January 07, 2015, 01:05:23 PM »
Ah yes :) thanks Alan .. I'll modify above.
:) I was mainly just looking for an excuse to express admiration for my one true love.
Ummmm ..  :oops:

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

fervour

  • Guest
Re: {Challenge}Get the textstrings in each line of the mtext
« Reply #28 on: January 07, 2015, 01:35:11 PM »
I used Lee's code and updated the _splitwords section. What did I do wrong?

Code: [Select]
(defun c:s2w ( / _splitwords _textwidth ang dxf ent enx fun inc lst pnt sel spc tot wid )

(defun _splitwords (str del / pos)
  ;; RJP mod vl-string-search for readability and delimiter argument
  (if (setq pos (vl-string-search del str))
    (cons (substr str 1 pos) (_splitwords (substr str (+ pos (1+ (strlen del))))del))
    (list str)
  )
)

(setq str (vla-get-textstring (vlax-ename->vla-object (car (entsel)))))
(_splitwords str "\t")

    (defun _textwidth ( enx )
        ((lambda ( lst ) (- (caadr lst) (caar lst))) (textbox enx))
    )

    (if (setq sel (ssget "_:L" '((0 . "TEXT") (-4 . "<NOT") (-4 . "<OR") (72 . 3) (72 . 4) (72 . 5) (-4 . "OR>") (-4 . "NOT>"))))
        (repeat (setq inc (sslength sel))
            (setq ent (ssname sel (setq inc (1- inc)))
                  enx (entget ent)
                  tot 0.0
                  lst nil
            )
            (foreach item (_splitwords (cdr (assoc 1 enx)))
                (setq dxf (entget (entmakex (subst item (assoc 1 enx) enx)))
                      wid (_textwidth dxf)
                      tot (+ tot wid)
                      lst (cons (cons dxf wid) lst)
                )
            )
            (if (< 1 (length lst))
                (progn
                    (setq wid (_textwidth enx)
                          spc (/ (- wid tot) (float (1- (length lst))))
                          lst (reverse lst)
                          ang (cdr (assoc 50 enx))
                    )
                    (if
                        (and
                            (= 0 (cdr (assoc 72 enx)))
                            (= 0 (cdr (assoc 73 enx)))
                        )
                        (setq pnt (cdr (assoc 10 enx)))
                        (setq pnt (cdr (assoc 11 enx)))
                    )
                    (cond
                        (   (= (cdr (assoc 72 enx)) 0)
                            (setq fun (lambda ( a b ) (+ spc (cdr a))))
                        )
                        (   (= (cdr (assoc 72 enx)) 1)
                            (setq fun (lambda ( a b ) (+ spc (/ (+ (cdr a) (cdr b)) 2.0)))
                                  pnt (polar pnt (+ ang pi) (/ (- wid (cdar lst)) 2.0))
                            )
                        )
                        (   (= (cdr (assoc 72 enx)) 2)
                            (setq fun (lambda ( a b ) (+ spc (cdr b)))
                                  pnt (polar pnt (+ ang pi) (- wid (cdar lst)))
                            )
                        )
                    )
                    (mapcar
                        (function
                            (lambda ( a b / dxf )
                                (setq dxf (car a)
                                      dxf (subst (cons 10 pnt) (assoc 10 dxf) dxf)
                                      dxf (subst (cons 11 pnt) (assoc 11 dxf) dxf)
                                      pnt (polar pnt ang (fun a b))
                                )
                                (entmod dxf)
                            )
                        )
                        lst (append (cdr lst) '((nil . 0.0)))
                    )
                    (entdel ent)
                )
            )
        )
    )
    (princ)
)
(princ)

alanjt

  • Needs a day job
  • Posts: 5352
  • Standby for witty remark...
Re: {Challenge}Get the textstrings in each line of the mtext
« Reply #29 on: January 07, 2015, 07:41:46 PM »
Ah yes :) thanks Alan .. I'll modify above.
:) I was mainly just looking for an excuse to express admiration for my one true love.
Ummmm ..  :oops:
I love you too, but I love pizza more.
Civil 3D 2019 ~ Windohz 7 64bit
Dropbox