TheSwamp
Code Red => AutoLISP (Vanilla / Visual) => Topic started by: cmwade77 on October 28, 2010, 12:30:55 PM
-
Ok, we are switching to stacked fractions here (finally).
So, I have a couple of challenges to come up with solutions to:
- Find a way to turn on AutoStacking via our startup LISP routines and set it to use a / to separate the numbers, not a -
- Find an easy way (LISP routine is preferred) to change all fractions to be stacked fraction
I have some ideas where to start on the second one, but I have no clue for the first one. If anyone has any ideas, I would love to hear them.
Correction: I thought I had an idea of where to start on the second one, but the method doesn't work, so any ideas there would be appreciated as well.
-
With regards to first one, I believe the settings are stored here:
(strcat "HKEY_CURRENT_USER\\" (vlax-product-key) "\\MTEXT")
Don't quote me on that though...
As for the second, I should imagine you could use a RegExp expression to replaces strings matching something like (\S)/(\S), then replace it with {$1#$2} or similar..
-
Find an easy way (LISP routine is preferred) to change all fractions to be stacked fraction
For DIMENSIONs without overridden text, it should be as easy as changing the fraction type in the dimension style.
For text overrides in DIMENSIONs, & MTEXT, you will first need to decide what the relative height of the fractions will be, and what type of fraction bar.
So, for example, if you want the relative height of the fractions to be 0.75, with a diagonal fraction bar,
3/8 becomes -> {\H0.75x;\S3#8;}
You will need to find the n/m type fractions & substitute the stacked fraction representation.
-
You may want to make sure all required fractions are available in the font you are using in order to support non-MTEXT entities like attributes. I seem to remember the OOTB RomanS.shx not having the "3/4" symbol defined, among others.
-
Actually, with modern stacking that is not an issue any more, AutoCAD now takes and makes the first number a superscript and the second number a subscript and adjusts the / between them. This is one of the reasons that stacked fractions are not accepted here.
-
Ok, here is what I have so far, please see the attached screenshot for an example of what happens to the text....any ideas?
-
Did you use the curly braces?
EDIT: Sorry, didn't see you attached the code...
-
you forgot to escape the backslash preceding the H:
"{\H0.7x;\\S"
here is a more compact way of testing for a numerical character:
(defun isdigit (char)
(if (> 58 (ascii char) 47) char nil)
)
-
This needs a lot more error trapping, but this is where I was going with the Regular Expression usage:
(defun c:test ( / RegEx i ss e )
(vl-load-com)
;; © Lee Mac 2010
(setq RegEx (vlax-create-object "VBScript.RegExp"))
(if (setq i -1 ss (ssget "_:L" '((0 . "MTEXT"))))
(while (setq e (ssname ss (setq i (1+ i))))
(vla-put-TextString (vlax-ename->vla-object e)
(LM:RegExReplace RegEx "{\\H0.7x;\\S$1#$2;}" "-?(\\d+)/(\\d+)" (LM:GetTextString e))
)
)
)
(vlax-release-object RegEx)
(princ)
)
(defun LM:RegExReplace ( reg new pat str )
;; © Lee Mac 2010
(mapcar '(lambda ( prop value ) (vlax-put-property reg prop value)) '(pattern global ignorecase) (list pat actrue acfalse))
(vlax-invoke reg 'replace str new)
)
(defun LM:GetTextString ( ent )
;; © Lee Mac 2010
( (lambda ( string )
(mapcar
(function
(lambda ( pair )
(if (vl-position (car pair) '(1 3))
(setq string (strcat string (cdr pair)))
)
)
)
(entget ent)
)
string
)
""
)
)
-
Cool, Lee :)
Probably want to prefix the string with center justification code:
(strcat "\\A1;" <yourstring>)
-
Cool, Lee :)
Probably want to prefix the string with center justification code:
(strcat "\\A1;" <yourstring>)
Thanks Herman 8-)
-
you forgot to escape the backslash preceding the H:
"{\H0.7x;\\S"
Thank you, I can't believe that I missed it.
Lee,
I like your code, but I definitely do not understand it; however, we will often have fractions like: 12/15
Now here comes the challenge:
We will also have factions like: 2-12/15
These need to have the dash removed and the 12/15 stacked
Ok, I think I got it, including getting rid of the dash, I do need some more testing, so please let me know what you think, I have attached the code here.
-
Code updated to allow for the dash :-)
-
Lee,
The only issue I had was that it would not stack: 123/256 for example, can you replicate this? It woul only stack one number before and after the /
-
Lee,
The only issue I had was that it would not stack: 123/256 for example, can you replicate this? It woul only stack one number before and after the /
Ah yes, I was only testing with single digits....
Updated.
-
Lee, I think your name appears in our customization more than mine. :-D
Thank you, I think i understand some of your code, but I don't understand the following bits of your code:
(setq RegEx (vlax-create-object "VBScript.RegExp"))
(LM:RegExReplace RegEx "{\\H0.7x;\\S$1#$2;}" "-?(\\d+)/(\\d+)" (LM:GetTextString e))
(defun LM:RegExReplace ( reg new pat str )
;; © Lee Mac 2010
(mapcar '(lambda ( prop value ) (vlax-put-property reg prop value)) '(pattern global ignorecase) (list pat actrue acfalse))
(vlax-invoke reg 'replace str new)
)
-
That's the part that uses Regular Expressions to make the replacements, Joe Burke introduced me to those whilst working on the Batch Find & Replace program.
I use this reference:
http://msdn.microsoft.com/en-us/library/yab2dx62%28VS.85%29.aspx (http://msdn.microsoft.com/en-us/library/yab2dx62%28VS.85%29.aspx)
-
Wow, I am going to have to look into that further, when I have more time. Right now, I am trying to catch up with the standards changes that my boss approved (finally) and trying to get "real work" out....LOL
-
With regards to first one, I believe the settings are stored here:
(strcat "HKEY_CURRENT_USER\\" (vlax-product-key) "\\MTEXT")
Don't quote me on that though...
As for the second, I should imagine you could use a RegExp expression to replaces strings matching something like (\S)/(\S), then replace it with {$1#$2} or similar..
Yes, that is indeed where it is stored, here is what I have:
* EDIT: I got it working now:
(if (/= (vl-registry-read (strcat "HKEY_CURRENT_USER\\" (vlax-product-key) "\\MTEXT") "AutoStack") 1)
(vl-registry-write (strcat "HKEY_CURRENT_USER\\" (vlax-product-key) "\\MTEXT") "AutoStack" 1)
)
(if (/= (vl-registry-read (strcat "HKEY_CURRENT_USER\\" (vlax-product-key) "\\MTEXT") "ConvertStackToArch") 1)
(vl-registry-write (strcat "HKEY_CURRENT_USER\\" (vlax-product-key) "\\MTEXT") "ConvertStackToArch" 1)
)
(if (/= (vl-registry-read (strcat "HKEY_CURRENT_USER\\" (vlax-product-key) "\\MTEXT") "TrimLeadingStackBlank") 1)
(vl-registry-write (strcat "HKEY_CURRENT_USER\\" (vlax-product-key) "\\MTEXT") "TrimLeadingStackBlank" 1)
)
-
lol why not set a variable:
(setq root (vl-registry-read (strcat "HKEY_CURRENT_USER\\" (vlax-product-key) "\\MTEXT"))
Save you some typing :-D
I suppose you could also use an expression like this, but it makes it less readable:
(mapcar
(function
(lambda ( key value )
(if (/= value (vl-registry-read root key))
(vl-registry-write root key value)
)
)
)
'("AutoStack" "ConvertStackToArch" "TrimLeadingStackBlank")
'(1 1 1)
)
-
Didn't try this, but is it necessary to read the key first? Can't you just write to the register:
(vl-registry-write root "AutoStack" 1)
(vl-registry-write root "ConvertStackToArch" 1)
(vl-registry-write root "TrimLeadingStackBlank" 1)
-
Didn't try this, but is it necessary to read the key first? Can't you just write to the register:
(vl-registry-write root "AutoStack" 1)
(vl-registry-write root "ConvertStackToArch" 1)
(vl-registry-write root "TrimLeadingStackBlank" 1)
I don't like writing to the registry if the values are already correctly set.....too many writes to the registry causes problems with windows.
-
[...] too many writes to the registry causes problems with windows.
Windows also checks the key/value first. If the value is already 1 then nothing happens. :)
-
Ok, I didn't know that, I just wanted to avoid the possibility of extra writes.
-
This needs a lot more error trapping, but this is where I was going with the Regular Expression usage:
(defun c:test ( / RegEx i ss e )
(vl-load-com)
;; © Lee Mac 2010
(setq RegEx (vlax-create-object "VBScript.RegExp"))
(if (setq i -1 ss (ssget "_:L" '((0 . "MTEXT"))))
(while (setq e (ssname ss (setq i (1+ i))))
(vla-put-TextString (vlax-ename->vla-object e)
(LM:RegExReplace RegEx "{\\H0.7x;\\S$1#$2;}" "-?(\\d+)/(\\d+)" (LM:GetTextString e))
)
)
)
(vlax-release-object RegEx)
(princ)
)
(defun LM:RegExReplace ( reg new pat str )
;; © Lee Mac 2010
(mapcar '(lambda ( prop value ) (vlax-put-property reg prop value)) '(pattern global ignorecase) (list pat actrue acfalse))
(vlax-invoke reg 'replace str new)
)
(defun LM:GetTextString ( ent )
;; © Lee Mac 2010
( (lambda ( string )
(mapcar
(function
(lambda ( pair )
(if (vl-position (car pair) '(1 3))
(setq string (strcat string (cdr pair)))
)
)
)
(entget ent)
)
string
)
""
)
)
Lee,
This code works well, but I can't seem to get it to work with MLEADERs. Please note that I have tried removing the filter and just selected the mleaders to experiment with. Any ideas on how to accomplish this? The formatting is the same as for MTEXT.
EDIT: I think I got it, please see attached code and let me know if there is a better way to handle this.
-
Ok, one more question on this, does anyone have any ideas on how to modify this to work with tables?
I am going to keep hacking at it, but haven't been able to get anywhere yet.