Author Topic: clean up the formatting of a MTEXT string  (Read 3850 times)

0 Members and 1 Guest are viewing this topic.

BIGAL

  • Swamp Rat
  • Posts: 1417
  • 40 + years of using Autocad
Re: clean up the formatting of a MTEXT string
« Reply #15 on: December 13, 2023, 05:27:26 PM »
My $0.05
Edit mtext replace "\n" with "-"
Strip mtext re Lee-mac
Parse to list "-" re Lee-mac. ie use 45 is "-"

Code: [Select]
; thanks to Lee-mac for this defun
;renamed to suit delimeter value in this case -
(defun csv->lst45  ( str / pos )
(if (setq pos (vl-string-position 45 str))
    (cons (substr str 1 pos) (csv->lst (substr str (+ pos 2))))
    (list str)
    )
)

A man who never made a mistake never made anything

xdcad

  • Bull Frog
  • Posts: 492
Re: clean up the formatting of a MTEXT string
« Reply #16 on: December 13, 2023, 06:55:31 PM »
Code - Auto/Visual Lisp: [Select]
  1. Command: (XD::MTEXT:UNFORMATSTRING (entlast))
  2. ("agafsg34" "fsfga" "ggggggg")
  3.  

Code - Auto/Visual Lisp: [Select]
  1. (defun XD::Mtext:UnformatString (mtxt / data)
  2.   (defun groupbykey (lst / tmp out)
  3.     (setq
  4.       lst (vl-sort lst
  5.                    (function (lambda (x1 x2) (> (car x1) (car x2))))
  6.           )
  7.     ) ;_sort
  8.     (setq tmp (list (cdar lst) (caar lst))) ;_first
  9.     (foreach item (cdr lst)
  10.       (if (= (car item) (last tmp))
  11.         (setq tmp (cons (cdr item) tmp))
  12.         (setq out (cons (reverse tmp) out)
  13.               tmp (list (cdr item) (car item))
  14.         )
  15.       )
  16.     )
  17.     (cons (reverse tmp) out) ;_last
  18.   )
  19.   (if (setq data (xdrx-mtext-fragments mtxt))
  20.     (progn
  21.       (setq data (mapcar '(lambda (x)
  22.                              (list (cadr (cadr (assoc "kLocation" x)))
  23.                                    (car (cadr (assoc "kLocation" x)))
  24.                                    (cadr (assoc "kTextString" x))
  25.                              )
  26.                            )
  27.                           data
  28.                   )
  29.             data (reverse (groupbykey data))
  30.       )
  31.       (mapcar
  32.         '(lambda (x) (apply 'strcat x))
  33.           (mapcar '(lambda (x) (mapcar 'cadr x)) (mapcar 'cdr data))
  34.       )
  35.     )
  36.   )
  37. )
« Last Edit: December 13, 2023, 08:10:45 PM by xdcad »
The code I wrote uses XDRX-API,which can be downloaded from github.com and is updated at any time.
===================================
https://github.com/xdcad
https://sourceforge.net/projects/xdrx-api-zip/
http://bbs.xdcad.net

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8712
  • AKA Daniel
Re: clean up the formatting of a MTEXT string
« Reply #17 on: December 13, 2023, 07:23:17 PM »
@xdcad
You can also add something like this as a utility to strip mtext formatting

Code - C++: [Select]
  1.         //.formatted string
  2.         AcValue acval(val);
  3.         acutPrintf(acval.format(AcValue::kIgnoreMtextFormat));
  4.  


xdcad

  • Bull Frog
  • Posts: 492
Re: clean up the formatting of a MTEXT string
« Reply #18 on: December 13, 2023, 08:11:58 PM »
@xdcad
You can also add something like this as a utility to strip mtext formatting

Code - C++: [Select]
  1.         //.formatted string
  2.         AcValue acval(val);
  3.         acutPrintf(acval.format(AcValue::kIgnoreMtextFormat));
  4.  

Thank you, I'll try
The code I wrote uses XDRX-API,which can be downloaded from github.com and is updated at any time.
===================================
https://github.com/xdcad
https://sourceforge.net/projects/xdrx-api-zip/
http://bbs.xdcad.net

xdcad

  • Bull Frog
  • Posts: 492
Re: clean up the formatting of a MTEXT string
« Reply #19 on: December 13, 2023, 09:40:07 PM »
@xdcad
You can also add something like this as a utility to strip mtext formatting

Code - C++: [Select]
  1.         //.formatted string
  2.         AcValue acval(val);
  3.         acutPrintf(acval.format(AcValue::kIgnoreMtextFormat));
  4.  

Code - Auto/Visual Lisp: [Select]
  1. Command: (setq a (xdrx-mtext-unformat a))
  2. "agafsg34\r\n\r\n\nfsfga\r\n\r\n\nggggggg"
  3. Command: (xdrx-string-regexps "[^\\r\\n]+" a)
  4. ("agafsg34" "fsfga" "gggggggg")

Code - C++: [Select]
  1. int MTextUnformat()
  2. {
  3.         resbuf* rb = ads_getargs();
  4.         if (!rb)
  5.         {
  6.                 return RSRSLT;
  7.         }
  8.         AcDbObjectId id;
  9.         const TCHAR* str = NULL;
  10.         if (rb->restype == RTENAME)
  11.         {
  12.                 if (acdbGetObjectId(id, rb->resval.rlname) == eOk)
  13.                 {
  14.                         AcDbMText* pMtext;
  15.                         if (acdbOpenObject(pMtext, id, kForRead) == eOk)
  16.                         {
  17.                                 str = pMtext->contents();
  18.                                 pMtext->close();
  19.                         }
  20.                 }
  21.         }
  22.         else if (rb->restype == RTSTR)
  23.         {
  24.                 str = rb->resval.rstring;
  25.         }
  26.         else {
  27.                 return RSRSLT;
  28.         }
  29.         AcValue acval(str);
  30.         ads_retstr(acval.format(AcValue::kIgnoreMtextFormat));
  31.         return RSRSLT;
  32. }
The code I wrote uses XDRX-API,which can be downloaded from github.com and is updated at any time.
===================================
https://github.com/xdcad
https://sourceforge.net/projects/xdrx-api-zip/
http://bbs.xdcad.net

JohnK

  • Administrator
  • Seagull
  • Posts: 10648
Re: clean up the formatting of a MTEXT string
« Reply #20 on: December 14, 2023, 09:57:20 AM »
@xdcad
While passing by I noticed your function and had a few quick questions.
Code - C++: [Select]
  1. int MTextUnformat() {                                   // Add function header!!
  2.         // MTextUnformat
  3.         // Unformats a text string. ...
  4.         //
  5.         // ARGS:
  6.         //
  7.         // RETURNS:
  8.         resbuf* rb = ads_getargs();
  9.         if (!rb) {
  10.                 return RSRSLT;
  11.         }
  12.         AcDbObjectId id;
  13.         const TCHAR* str = NULL;
  14.         if (rb->restype == RTENAME) {                   // Should you consider
  15.                                                         // a separate function
  16.                                                         // to replace nested
  17.                                                         // if's below?
  18.                 if (acdbGetObjectId(id, rb->resval.rlname) == eOk) {
  19.                         AcDbMText* pMtext;
  20.                         if (acdbOpenObject(pMtext, id, kForRead) == eOk) {
  21.                                 str = pMtext->contents();
  22.                                 pMtext->close();
  23.                         }
  24.                 }
  25.         }
  26.         else if (rb->restype == RTSTR) {                // Should this be IF?
  27.                 str = rb->resval.rstring;
  28.         }
  29.         else {                                          // Is this ELSE needed? -i.e. checked already.
  30.                 return RSRSLT;
  31.         }
  32.         AcValue acval(str);
  33.         ads_retstr(acval.format(AcValue::kIgnoreMtextFormat));
  34.         return RSRSLT;
  35. }
  36.  
TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org

dwaschnia

  • Mosquito
  • Posts: 13
Re: clean up the formatting of a MTEXT string
« Reply #21 on: December 14, 2023, 10:53:29 AM »
low iq version :)

Code - Auto/Visual Lisp: [Select]
  1. (defun c:uform ( / l len en start i ss x )
  2.   (setq len (entlast))
  3.   (setq en (car (entsel)))
  4.   (command "_copybase" "_non" "0,0" en "")
  5.   (command "_pasteclip" "_non" "0,0")
  6.   (command "_explode" (entlast))
  7.   (setq start (entnext len))
  8.         (setq ss (ssadd))
  9.         (while start
  10.                 (setq ss (ssadd start ss))
  11.                 (setq start (entnext start))
  12.         )
  13.   (repeat (setq i (sslength ss))
  14.     (setq l (append l (list "\\P")))
  15.     (setq l (append l (list (vla-get-textstring (setq x (vlax-ename->vla-object (ssname ss (setq i (1- i)))))))))
  16.     (vla-delete x)
  17.   )
  18.   (vla-put-textstring (vlax-ename->vla-object en) (apply 'strcat (reverse (cdr l))))
  19. )

xdcad

  • Bull Frog
  • Posts: 492
Re: clean up the formatting of a MTEXT string
« Reply #22 on: December 14, 2023, 06:43:08 PM »
@xdcad
While passing by I noticed your function and had a few quick questions.
Code - C++: [Select]
  1. int MTextUnformat() {                                   // Add function header!!
  2.         // MTextUnformat
  3.         // Unformats a text string. ...
  4.         //
  5.         // ARGS:
  6.         //
  7.         // RETURNS:
  8.         resbuf* rb = ads_getargs();
  9.         if (!rb) {
  10.                 return RSRSLT;
  11.         }
  12.         AcDbObjectId id;
  13.         const TCHAR* str = NULL;
  14.         if (rb->restype == RTENAME) {                   // Should you consider
  15.                                                         // a separate function
  16.                                                         // to replace nested
  17.                                                         // if's below?
  18.                 if (acdbGetObjectId(id, rb->resval.rlname) == eOk) {
  19.                         AcDbMText* pMtext;
  20.                         if (acdbOpenObject(pMtext, id, kForRead) == eOk) {
  21.                                 str = pMtext->contents();
  22.                                 pMtext->close();
  23.                         }
  24.                 }
  25.         }
  26.         else if (rb->restype == RTSTR) {                // Should this be IF?
  27.                 str = rb->resval.rstring;
  28.         }
  29.         else {                                          // Is this ELSE needed? -i.e. checked already.
  30.                 return RSRSLT;
  31.         }
  32.         AcValue acval(str);
  33.         ads_retstr(acval.format(AcValue::kIgnoreMtextFormat));
  34.         return RSRSLT;
  35. }
  36.  

=============
Code - C++: [Select]
  1. else if (rb->restype == RTSTR) {                // Should this be IF?
  2.                 str = rb->resval.rstring;
  3.         }
Supports two types of parameters, one is the MTEXT entity name, and the other is a formatted string

=============

Code - C++: [Select]
  1. else {                                          // Is this ELSE needed? -i.e. checked already.
  2.                 return RSRSLT;
  3.         }

If it is not an entity name or a string, other parameters given to the function will not be processed and will exit directly.
« Last Edit: December 14, 2023, 06:48:27 PM by xdcad »
The code I wrote uses XDRX-API,which can be downloaded from github.com and is updated at any time.
===================================
https://github.com/xdcad
https://sourceforge.net/projects/xdrx-api-zip/
http://bbs.xdcad.net

xdcad

  • Bull Frog
  • Posts: 492
Re: clean up the formatting of a MTEXT string
« Reply #23 on: December 14, 2023, 06:58:45 PM »
Code - C++: [Select]
  1. int MTextUnformat()
  2. {
  3.         //param:
  4.         // 1:mtext entity name
  5.         // or
  6.         // 2:formatted string
  7.         // t or nil: t return list,
  8.         //           nil return unformatted string
  9.         resbuf* rb = ads_getargs();
  10.         if (!rb)
  11.         {
  12.                 return RSRSLT;
  13.         }
  14.         AcDbObjectId id;
  15.         const TCHAR* str = NULL;
  16.         bool bRetList = true;
  17.         if (rb->restype == RTENAME)
  18.         {
  19.                 if (acdbGetObjectId(id, rb->resval.rlname) == eOk)
  20.                 {
  21.                         AcDbMText* pMtext;
  22.                         if (acdbOpenObject(pMtext, id, kForRead) == eOk)
  23.                         {
  24.                                 str = pMtext->contents();
  25.                                 pMtext->close();
  26.                         }
  27.                 }
  28.                 else {
  29.                         return RSRSLT;
  30.                 }
  31.         }
  32.         else if (rb->restype == RTSTR)
  33.         {
  34.                 str = rb->resval.rstring;
  35.         }
  36.         else {
  37.                 return RSRSLT;
  38.         }
  39.         rb = rb->rbnext;
  40.         if (rb && rb->restype == RTT)
  41.         {
  42.                 bRetList = false;
  43.         }
  44.  
  45.         AcValue acval(str);
  46.         const TCHAR *str1 = acval.format(AcValue::kIgnoreMtextFormat);
  47.         if (bRetList)
  48.         {
  49.                 XdRbList strArr1;
  50.                 if (XdGeUtils::XDRegExpS(str1, _T("[^\r\n]+"), strArr1, 14, true, true))
  51.                 {
  52.                         strArr1.toLisp(0, 1);
  53.                 }
  54.         }
  55.         else {
  56.                 ads_retstr(str1);
  57.         }
  58.         return RSRSLT;
  59. }
  60.  

Code - Auto/Visual Lisp: [Select]
  1. Command: !str
  2. "a{\\fMS UI Gothic|b1|i1|c0|p34;\\C32;\\c2648525;gaf}sg34\\Pfsf{\\L\\Oga\\P}ggggggg"
  3. Command: (xdrx-mtext-unformat str)
  4. ("agafsg34" "fsfga" "ggggggg")
  5. Command: (xdrx-mtext-unformat str t)
  6. "agafsg34\r\n\r\n\nfsfga\r\n\r\n\nggggggg"
  7.  
  8. Command: (xdrx-mtext-unformat (car (entsel)))
  9. Select object: ("agafsg34" "fsfga" "ggggggg")
  10.  
  11. Command: (xdrx-mtext-unformat (car (entsel)) t)
  12. Select object: "agafsg34\r\n\r\n\nfsfga\r\n\r\n\nggggggg"
  13.  
The code I wrote uses XDRX-API,which can be downloaded from github.com and is updated at any time.
===================================
https://github.com/xdcad
https://sourceforge.net/projects/xdrx-api-zip/
http://bbs.xdcad.net

JohnK

  • Administrator
  • Seagull
  • Posts: 10648
Re: clean up the formatting of a MTEXT string
« Reply #24 on: December 14, 2023, 08:15:39 PM »

---->%

=============
Code - C++: [Select]
  1. else if (rb->restype == RTSTR) {                // Should this be IF?
  2.                 str = rb->resval.rstring;
  3.         }
Supports two types of parameters, one is the MTEXT entity name, and the other is a formatted string

=============

Code - C++: [Select]
  1. else {                                          // Is this ELSE needed? -i.e. checked already.
  2.                 return RSRSLT;
  3.         }

If it is not an entity name or a string, other parameters given to the function will not be processed and will exit directly.

You and I have very different coding styles. I was only trying to point out that most times you can eliminate the if-else-ifelse construct. Most of my code looks like this (I make a lot of small single use functions which preform specific things). I cannot keep all those nested if statements straight, myself.

Code - C++: [Select]
  1. //-------------------------------------------------------------------
  2. // process_path
  3. // This function will decide whether a file is a regular file or a
  4. // directory and pass it to the proper function for handling.
  5. //
  6. // ARGS
  7. //  char* directory     :   Path of a file
  8. //
  9. // RETURN
  10. // void
  11. //-------------------------------------------------------------------
  12. void process_path(char *path) {
  13.   /* Process files as files, directories as directories, and skip
  14.    * everything else. */
  15.   struct stat sbuf;
  16.   if (stat(path, &sbuf)) {
  17.     perror("Failed to open directory");
  18.     return;
  19.   }
  20.   if (S_ISREG(sbuf.st_mode)) {
  21.     process_file(path);
  22.   }
  23.   if (S_ISDIR(sbuf.st_mode)) {
  24.     process_directory(path);
  25.   }
  26. }
TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8712
  • AKA Daniel
Re: clean up the formatting of a MTEXT string
« Reply #25 on: December 14, 2023, 10:30:02 PM »
From a performance perspective,
if , else if , else may be faster because the compiler can build a jump table instead of having a bunch of branches

It’s not so pretty from a code readability perspective. I tend to use a switch statement for checking ints, it’s fast and its pretty. 
I would use a smart pointer for AcDbMText

kdub_nz

  • Mesozoic keyThumper
  • SuperMod
  • Water Moccasin
  • Posts: 2140
  • class keyThumper<T>:ILazy<T>
Re: clean up the formatting of a MTEXT string
« Reply #26 on: December 14, 2023, 10:50:47 PM »
Quote from:  Dan
I would use a smart pointer for AcDbMText

Is it possible that a lot of this code was generated before smart pointers were available ??
[added]
. . . and the code base is probably used for multiple acad versions
[/added]

Would this be a case of "it's not broken so don't fix it" ?
or are there discernable advantages ?

« Last Edit: December 14, 2023, 11:14:39 PM by kdub_nz »
Called Kerry in my other life
Retired; but they dragged me back in !

I live at UTC + 13.00

---
some people complain about loading the dishwasher.
Sometimes the question is more important than the answer.

xdcad

  • Bull Frog
  • Posts: 492
Re: clean up the formatting of a MTEXT string
« Reply #27 on: December 15, 2023, 12:02:24 AM »
Quote from:  Dan
I would use a smart pointer for AcDbMText

Is it possible that a lot of this code was generated before smart pointers were available ??
[added]
. . . and the code base is probably used for multiple acad versions
[/added]

Would this be a case of "it's not broken so don't fix it" ?
or are there discernable advantages ?

yes, autocad 2004-2024
vc7-vs2022
The code I wrote uses XDRX-API,which can be downloaded from github.com and is updated at any time.
===================================
https://github.com/xdcad
https://sourceforge.net/projects/xdrx-api-zip/
http://bbs.xdcad.net

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8712
  • AKA Daniel
Re: clean up the formatting of a MTEXT string
« Reply #28 on: December 15, 2023, 02:06:03 AM »
Quote from:  Dan
I would use a smart pointer for AcDbMText

Is it possible that a lot of this code was generated before smart pointers were available ??
[added]
. . . and the code base is probably used for multiple acad versions
[/added]

Would this be a case of "it's not broken so don't fix it" ?
or are there discernable advantages ?

Good questions

I don’t know when AcDbObjectPointer was added to ARX. I’m guessing that it’s been in forever.
If it’s not in ARX2000, it’s just a header…

Code - C++: [Select]
  1. AcDbObjectPointer<AcDbMText> pMtext (id, AcDb::kForRead);

This line tells the reader:
A, the pointer is guaranteed to be an object derived from AcDbMText.
B, that the object is guaranteed to be closed, even if there’s an exception.

Quote
Would this be a case of "it's not broken so don't fix it" ?
This is a newly created function, you’re in the code, might as well improve it

Of course, it’s not my project, just my opinion

kdub_nz

  • Mesozoic keyThumper
  • SuperMod
  • Water Moccasin
  • Posts: 2140
  • class keyThumper<T>:ILazy<T>
Re: clean up the formatting of a MTEXT string
« Reply #29 on: December 15, 2023, 02:51:23 AM »
Quote
This is a newly created function, you’re in the code, might as well improve it

ahh, yes good point.


wait, wouldn't one of the old compliers spit the dummy ??
Called Kerry in my other life
Retired; but they dragged me back in !

I live at UTC + 13.00

---
some people complain about loading the dishwasher.
Sometimes the question is more important than the answer.