Author Topic: AutoStacking  (Read 7892 times)

0 Members and 1 Guest are viewing this topic.

cmwade77

  • Swamp Rat
  • Posts: 1443
AutoStacking
« 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.
« Last Edit: October 28, 2010, 12:48:35 PM by cmwade77 »

Lee Mac

  • Seagull
  • Posts: 12905
  • London, England
Re: AutoStacking
« Reply #1 on: October 28, 2010, 12:58:01 PM »
With regards to first one, I believe the settings are stored here:

Code: [Select]
(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..

« Last Edit: October 28, 2010, 01:01:09 PM by Lee Mac »

hermanm

  • Guest
Re: AutoStacking
« Reply #2 on: October 28, 2010, 01:38:15 PM »
Quote
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.

dgorsman

  • Water Moccasin
  • Posts: 2437
Re: AutoStacking
« Reply #3 on: October 28, 2010, 02:07:56 PM »
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.
If you are going to fly by the seat of your pants, expect friction burns.

try {GreatPower;}
   catch (notResponsible)
      {NextTime(PlanAhead);}
   finally
      {MasterBasics;}

cmwade77

  • Swamp Rat
  • Posts: 1443
Re: AutoStacking
« Reply #4 on: October 28, 2010, 03:57:22 PM »
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.

cmwade77

  • Swamp Rat
  • Posts: 1443
Re: AutoStacking
« Reply #5 on: October 28, 2010, 07:15:36 PM »
Ok, here is what I have so far, please see the attached screenshot for an example of what happens to the text....any ideas?

Lee Mac

  • Seagull
  • Posts: 12905
  • London, England
Re: AutoStacking
« Reply #6 on: October 28, 2010, 08:17:59 PM »
Did you use the curly braces?

EDIT: Sorry, didn't see you attached the code...
« Last Edit: October 28, 2010, 09:21:57 PM by Lee Mac »

hermanm

  • Guest
Re: AutoStacking
« Reply #7 on: October 28, 2010, 09:21:19 PM »
you forgot to escape the backslash preceding the H:

Code: [Select]
"{\H0.7x;\\S"

here is a more compact way of testing for a numerical character:

Code: [Select]
(defun isdigit (char)
  (if (> 58 (ascii char) 47) char nil)
)

Lee Mac

  • Seagull
  • Posts: 12905
  • London, England
Re: AutoStacking
« Reply #8 on: October 28, 2010, 09:33:53 PM »
This needs a lot more error trapping, but this is where I was going with the Regular Expression usage:

Code: [Select]
(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
     )
    ""
  )
)
« Last Edit: October 29, 2010, 01:03:11 PM by Lee Mac »

hermanm

  • Guest
Re: AutoStacking
« Reply #9 on: October 28, 2010, 11:13:18 PM »
Cool, Lee :)

Probably want to prefix the string with center justification code:

(strcat "\\A1;" <yourstring>)

Lee Mac

  • Seagull
  • Posts: 12905
  • London, England
Re: AutoStacking
« Reply #10 on: October 29, 2010, 06:54:05 AM »
Cool, Lee :)

Probably want to prefix the string with center justification code:

(strcat "\\A1;" <yourstring>)

Thanks Herman  8-)

cmwade77

  • Swamp Rat
  • Posts: 1443
Re: AutoStacking
« Reply #11 on: October 29, 2010, 11:36:28 AM »
you forgot to escape the backslash preceding the H:

Code: [Select]
"{\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.
« Last Edit: October 29, 2010, 12:17:30 PM by cmwade77 »

Lee Mac

  • Seagull
  • Posts: 12905
  • London, England
Re: AutoStacking
« Reply #12 on: October 29, 2010, 12:23:04 PM »
Code updated to allow for the dash  :-)

cmwade77

  • Swamp Rat
  • Posts: 1443
Re: AutoStacking
« Reply #13 on: October 29, 2010, 12:57:35 PM »
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 Mac

  • Seagull
  • Posts: 12905
  • London, England
Re: AutoStacking
« Reply #14 on: October 29, 2010, 01:00:41 PM »
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.

cmwade77

  • Swamp Rat
  • Posts: 1443
Re: AutoStacking
« Reply #15 on: October 29, 2010, 01:32:20 PM »
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:
Code: [Select]
(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)
)

Lee Mac

  • Seagull
  • Posts: 12905
  • London, England
Re: AutoStacking
« Reply #16 on: October 29, 2010, 01:35:58 PM »
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

cmwade77

  • Swamp Rat
  • Posts: 1443
Re: AutoStacking
« Reply #17 on: October 29, 2010, 01:39:52 PM »
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

cmwade77

  • Swamp Rat
  • Posts: 1443
Re: AutoStacking
« Reply #18 on: October 29, 2010, 02:50:08 PM »
With regards to first one, I believe the settings are stored here:

Code: [Select]
(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:
Code: [Select]
(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)
)
« Last Edit: October 29, 2010, 04:11:19 PM by cmwade77 »

Lee Mac

  • Seagull
  • Posts: 12905
  • London, England
Re: AutoStacking
« Reply #19 on: October 29, 2010, 06:49:28 PM »
lol why not set a variable:

Code: [Select]
(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:

Code: [Select]
(mapcar
  (function
    (lambda ( key value )
      (if (/= value (vl-registry-read root key))
        (vl-registry-write root key value)
      )
    )
  )
  '("AutoStack" "ConvertStackToArch" "TrimLeadingStackBlank")
  '(1 1 1)
)

Crank

  • Water Moccasin
  • Posts: 1503
Re: AutoStacking
« Reply #20 on: October 30, 2010, 03:52:42 PM »
Didn't try this, but is it necessary to read the key first? Can't you just write to the register:
Code: [Select]
(vl-registry-write root "AutoStack" 1)
(vl-registry-write root "ConvertStackToArch" 1)
(vl-registry-write root "TrimLeadingStackBlank" 1)
Vault Professional 2023     +     AEC Collection

cmwade77

  • Swamp Rat
  • Posts: 1443
Re: AutoStacking
« Reply #21 on: November 02, 2010, 11:29:04 AM »
Didn't try this, but is it necessary to read the key first? Can't you just write to the register:
Code: [Select]
(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.

Crank

  • Water Moccasin
  • Posts: 1503
Re: AutoStacking
« Reply #22 on: November 02, 2010, 12:00:10 PM »
[...] 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. :)
Vault Professional 2023     +     AEC Collection

cmwade77

  • Swamp Rat
  • Posts: 1443
Re: AutoStacking
« Reply #23 on: November 02, 2010, 12:30:25 PM »
Ok, I didn't know that, I just wanted to avoid the possibility of extra writes.

cmwade77

  • Swamp Rat
  • Posts: 1443
Re: AutoStacking
« Reply #24 on: November 03, 2010, 01:41:50 PM »
This needs a lot more error trapping, but this is where I was going with the Regular Expression usage:

Code: [Select]
(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.
« Last Edit: November 03, 2010, 02:33:50 PM by cmwade77 »

cmwade77

  • Swamp Rat
  • Posts: 1443
Re: AutoStacking
« Reply #25 on: November 09, 2010, 12:05:32 PM »
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.