Mtext problem

Mtext problem

zph
Collaborator Collaborator
2,814 Views
11 Replies
Message 1 of 12

Mtext problem

zph
Collaborator
Collaborator

Good day all!

 

Take a look at the attached picture.  Mtext A and B are the same except for their formatting codes.  Mtext A has them; B has had them stripped (by exploding the Mtext and then combined using TXT2MTXT).

 

I am able to identify a carriage returns in Mtext A by identifying the "\\P"s.  For Mtext B, however, I am not able to identify the hard carriage return based upon the "\\P", but the Mtext is still displayed as though it has them.  This leads me to the assumption that the carriage returns are still stored somewhere....

 

I want to pull the Mtext apart and assign each line to a variable regardless of the Mtext formatting.

 

Any ideas?

 

~Z

0 Likes
Accepted solutions (1)
2,815 Views
11 Replies
Replies (11)
Message 2 of 12

Kent1Cooper
Consultant
Consultant

That would be because the original uses hard returns to make new lines, not word wrapping based on the defined Width of its Mtext box [and may not even have any Width defined], whereas the result of TXT2MTXT combining decides on a box width from the selected objects, and the new breakdown into lines is the result of mere word wrapping resulting from that width -- no, the carriage returns are not saved anywhere.

 

One thing you can do is to use the fact that the results from an EXPLODE command become the "Previous" selection set.  Immediately after EXPLODE, try this:

 

(setq

  texts (ssget "_P"); the resulting pieces, in a selection set, in order from top to bottom

  A (cdr (assoc 1 (entget (ssname texts 0))))

  B (cdr (assoc 1 (entget (ssname texts 1))))

  C (cdr (assoc 1 (entget (ssname texts 2))))

); setq

 

Combine them with TXT2MTXT after doing that, if you still need them combined.

 

That assumes three and only three lines in the source.  If there might sometimes be different numbers of lines, that can also be accounted for with a little more sophistication in the code.

 

EDIT:

Another good reason to do it that way [i.e. before recombining if needed] is that depending on the relative lengths of different lines in the hard-returned version, the breakdown between lines can come out differently in the TXT2MTXTed combination than it was in the original:

TextConversion.PNG

I think TXT2MTXT determines the resulting Mtext box width from the longest line among those selected, and since it strings the entire combined content into one line without returns, leaving the line breaks to word wrapping, the shorter pieces in the upper lines in this example get shifted because more of them fit in that width.

Kent Cooper, AIA
Message 3 of 12

zph
Collaborator
Collaborator

Kent,

 

Thanks for the quick reply.

 

You answered my question.  However, your solution isn't an option.

 

Looks like I will need to incorporate additional string recognition into the code to account for the unformatted Mtext that doesn't include hard carriage returns.

 

Thanks!

~Z

0 Likes
Message 4 of 12

Kent1Cooper
Consultant
Consultant

@zph wrote:

....  However, your solution isn't an option.

.... I will need to incorporate additional string recognition ....


I'm curious as to why it's not an option.  What are the circumstances?  Can they be tweaked in some way to incorporate that approach, by doing something or other in a slightly different order, or something?  I can't suggest anything specific without more detail about where this is all coming from, but you might be surprised -- there could be a way around it.

 

If it really isn't an option, that additional string recognition would be comparatively simple if you could simply break the resulting string into substrings around spaces [there are several routines around here that will do that].  It will be much trickier if something you want saved as a single string includes a space within it, as one does in your example.  It may be possible if you can define only limited possible circumstances, such as that any single-letter "word" in the string should always be combined with the word before it, but that depends on the possible configurations of the pieces you will encounter.  Those are some of the reasons why the save-the-variables-before-recombining approach would be so much simpler, if there's some way to make it possible.

Kent Cooper, AIA
0 Likes
Message 5 of 12

joselggalan
Advocate
Advocate

Avoiding the problem by code.
Have you tried to disable the "Create word-wrap MText" option in the "TXT2MTXT" options?

 

 

2017-03-21_19-08-04.png

 

 

 

2017-03-21_19-06-42.png

 

 

 

Message 6 of 12

zph
Collaborator
Collaborator

Sure; in a nutshell.

 

This portion of code will reside in a routine that will be pulling data based upon a rather large selection set.

 

The user will identify the area of the drawing to pull data from by defining a crossing window.

 

There will be no user interaction from that point.

 

The routine will interpret formatted AND unformatted values of Mtext entities resulting from this selection set.

 

 

 

 

0 Likes
Message 7 of 12

zph
Collaborator
Collaborator

joselggalan,

 

While your reply doesn't provide a possible solution to my problem, I was not aware of the options within TXT2MTXT.

 

Thank you for the information!

 

~Z

0 Likes
Message 8 of 12

Kent1Cooper
Consultant
Consultant

That doesn't really tell me enough to understand why it can't pull the string content out of the pieces after Exploding and before re-assembling, as opposed to [for example, if it re-assembles the no-format pieces using the don't-word-wrap option in TXT2MTXT] subdividing around \\P elements, or something.

Kent Cooper, AIA
0 Likes
Message 9 of 12

zph
Collaborator
Collaborator

This routine will only read the Mtext entities, not modify them.

 

It will need to be able to effectively handle unformatted and formatted Mtext values.

 

I only added the statement pertaining how the Mtext entities became unformatted (exploding to TXT2MTEXT) because I was thinking it may help in identifying an answer to the absence of the "\\P" in the Mtext value.  I didn't realize the Mtext value was 'word-wrapping'.

 

Cheers!

0 Likes
Message 10 of 12

Kent1Cooper
Consultant
Consultant
Accepted solution

@zph wrote:

This routine will only read the Mtext entities, not modify them.

 

It will need to be able to effectively handle unformatted and formatted Mtext values.

....


So you may have some that have multiple lines via hard returns, and some that have them as a result of word wrapping, and some that might have things like font and/or color and/or size and/or other formatting within them, and what you want is to extract each line without formatting and save it into a text-string variable.

 

You can dump all internal formatting with a routine called StripMtext, links for which you can find with a Search.  That could presumably be modified to take the color/font/etc. formatting out of just the string content pulled from one, without modifying the Mtext object itself.  Then there are routines that will break a string apart around any kind of delimiter you want to specify, in this case presumably the \\P for those that use hard returns, and you could thereby get the unformatted content of each line.  But that won't get you the breakdown between lines when that comes from word wrapping.

 

I suspect the easiest thing to do would be to have a routine make a copy of the Mtext object, Explode the copy and put the contents into variables as in Post 2, and then get rid of the temporary pieces from the copy.  That would handle the breakdown into lines correctly no matter how it's arrived at, and eliminate all formatting.  Does that sound viable?

Kent Cooper, AIA
Message 11 of 12

zph
Collaborator
Collaborator

Here is the portion of code that pertains to this:

 

 

(setq ss3 (ssget "_C" 
		(list (car pt3) (- (cadr pt4) 0.5)) 
		pt4 
			'((0 . "MTEXT")(8 . "TEXT"))))

(setq eQd (cdr (assoc 1 (entget (ssname ss3 0)))))
(setq dLen (strlen eQd) i 0 iR ())	

(if (= (vl-string-search "\\P" eQd 0) nil)
	(progn
		(cond
			((/= (vl-string-search "P/P" eQd 0) nil)
				(setq 	hNL (vl-string-search "P/P" eQd 0)
					MISC "nil"
					HN (substr eQd 1 (+ hNL 3))
					EL (substr eQd (+ hNL 5)))
			)

			((/= (vl-string-search "PATCH PANEL" eQd 0) nil)
				(setq 	hNL (vl-string-search "PATCH PANEL" eQd 0)
					MISC "nil"
					HN (substr eQd 1 (+ hNL 11))
					EL (substr eQd (+ hNL 13)))
			)

			(T
				(foreach cZ cZiD
					(if (/= (vl-string-search cZ eQd 0) nil)
						(progn
						(setq hNL (vl-string-search cZ eQd 0) HN "")

						(if (> hNL 0)
						(setq i (1+ hNL) MISC (substr eQd 1 (1- hNL)))
						(setq i 1 MISC "nil")
						) ;if

						(while (/= (substr eQd i 1) " ")
						(setq HN (strcat HN (substr eQd i 1)) i (1+ i))
						) ;while

						(setq EL (substr eQd (1+ i)))
						) ;progn
					) ;if
				) ;foreach
			)
		) ;cond
	) ;progn

	(progn
		(while (<= i dLen)
			(if (/= (vl-string-search "\\P" eQd i) nil)
			(setq iR (cons (vl-string-search "\\P" eQd i) iR))
			) ;if
		(setq i (1+ i))
		) ;while

	(setq iR (vl-sort iR '<) i 0 iT 1 dList ())

		(while (<= i (length iR))
		(setq iD (nth i iR))

			(cond 
				((= i 0)
					(setq dList (cons (list (substr eQd iT iD)) dList) iT iD)
				)

				((< i (length iR))
					(setq dList (cons (list (substr eQd (+ iT 2) (- (- iD iT) 1))) dList) iT iD)
				)

				((= i (length iR))
					(setq dList (cons (list (substr eQd (+ iT 3))) dList))
				)
			) ;cond

		(setq i (1+ i))
		) ;while

	(setq dList (reverse dList) fList ())

		(foreach dL dList
			(if (/= (vl-string-search "{" (car dL)) nil)
				(setq 	sCo (vl-string-search ";" (car dL))
					newV (substr (car dL) (+ sCo 2) (- (strlen (car dL)) (+ sCo 2)))
					fList (cons (list newV) fList))

				(setq fList (cons (list (car dL)) fList))
			) ;if	
		) ;foreach

	(setq fList (reverse fList))

		(cond
			((= (length fList) 1) (setq MISC (car (nth 0 fList)) HN "nil" EL "nil"))
			((= (length fList) 2) (setq MISC "nil" HN (car (nth 0 fList)) EL (car (nth 1 fList))))
			((= (length fList) 3) (setq MISC (car (nth 0 fList)) HN (car (nth 1 fList)) EL (car (last fList))))
		) ;cond
	) ;progn
) ;if

 

0 Likes
Message 12 of 12

zph
Collaborator
Collaborator

Kent,

 

After months of successfully tweaking to accommodate formatting codes, I realize that I needed to change the way I was handling this portion of code.  Your idea about copying the mtext entity, exploding the copy, and capturing the individual text entity values and then deleting those entities was spot on.  I have since integrated this method into the routine.

 

I don't regret dealing/working with the formatting codes - I learned a lot and it was fun.  However, the routine needs to be at a state where I am not needing to repeatedly dive back into the code and changing it based upon circumstances that are outside of my control.

 

Thanks, Kent!

~Z

0 Likes