Author Topic: Lee Mac's Associative Textbox  (Read 1958 times)

0 Members and 1 Guest are viewing this topic.

HeavyThumper

  • Mosquito
  • Posts: 13
Lee Mac's Associative Textbox
« on: July 13, 2021, 03:20:10 PM »
Now that I'm getting on in years I can only absorb so much at a time. Just reading Lee's list of available routines can induce tremors - so now I just visit when I'm looking for a specific solution.

Looking for something else (and I forget what) - I found this incredible tbox command. Wow. Now I've got to try to understand what's going on so I can adapt this to my purposes - and I'm getting in trouble right away.

The first section sets an error handler. Good idea - I'll need to study that part a bit more so I can properly copy that in my other functions but at least the steps made sense. Then we have...
Code - Auto/Visual Lisp: [Select]
  1.     (setq tbox:off
  2.         (cond
  3.             (   (getdist (strcat "\nSpecify Offset Factor <" (rtos (cond (tbox:off) ((setq tbox:off 0.35))) 2 2) ">: ")))
  4.             (   tbox:off   )
  5.         )
  6.     )
  7.     (initget "Circle Slot Rectangle")

I know it's supposed to be cool to inline everything possible - and it's a little more intelligible when you're actively using the language. Delete whiny complaint - I need to learn this stuff. Ok - I'm reading this as:

  • Set a variable tbox:off to the result of a condition. Pause here - where is tbox:off declared? I don't see it in the c:tbox function header.
  • Now, reading from the inside out that interesting statement...
  • Initialize tbox:off to 0.35
  • That is then enclosed in parens a second time - because?
  • Now, test the value of tbox:off - which at this stage I think is undefined
  • if it's non-nil - set tbox:off to 0.35. Uh...I'm assuming this is some kind of
    protected initialization but the mechanism escapes me.
  • Now, take the (apparently) numberic result of that conditional, convert to a string, and call (getdist)
  • Digging into (getdist) I answered my original reason I started this post - this performs a user query. I only saw the initget and didn't understand where the Offset Factor prompt actually got displayed. At least I now understand this part.  :oops:
  • And...if the above process yields a positive result we...call (tbox:off) again?

Reading, re-reading, re-re-reading, googling docs...

Ok - I'm guessing the last occurrence of (tbox:off) is an assignment. But...doesn't that need an enclosing (setq)? I would have thought this needed to be written like:
Code - Auto/Visual Lisp: [Select]
  1. (setq tbox:off (getdist blah blah))
Because it looks to me like the last reference to (tbox:off) is the result of the (cond - which means the outer enclosing (setq wouldn't apply? Sigh.

Please tell me just how wrong I am - there's just too many basic language conventions I'm not used to.

JohnK

  • Administrator
  • Seagull
  • Posts: 10626
Re: Lee Mac's Associative Textbox
« Reply #1 on: July 13, 2021, 04:04:06 PM »
*phew!* I cannot follow that post.

That small code snip is a combination of the "RRB default method" and the "Aniphoric-if" (the `RRB default method` is something I named after R.RobertBell when he taught me something but the Aniphoric-if was a phrase coined by Paul Gramm).

See here for some explanations
https://www.theswamp.org/index.php?topic=28433.msg340206#msg340206

But if you don't want to read: #9 should be "return the result of "TBOX:OFF" and set the variable to that value".
TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org

ronjonp

  • Needs a day job
  • Posts: 7527
Re: Lee Mac's Associative Textbox
« Reply #2 on: July 13, 2021, 04:46:54 PM »
Maybe this helps you understand:

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

HeavyThumper

  • Mosquito
  • Posts: 13
Re: Lee Mac's Associative Textbox
« Reply #3 on: July 13, 2021, 04:58:04 PM »
*phew!* I cannot follow that post.
I appreciate that.
But if you don't want to read: #9 should be "return the result of "TBOX:OFF" and set the variable to that value".

If TBOX:OFF is a variable - how is setting the variable TBOX:OFF to itself viable. I don't follow this at all.

I read the linked article. THANK YOU! That helps a lot. I have more questions...but I guess I need to run some small tests and keep digging into the language.


HeavyThumper

  • Mosquito
  • Posts: 13
Re: Lee Mac's Associative Textbox
« Reply #4 on: July 13, 2021, 05:03:03 PM »
Maybe this helps you understand:

That was huge! THANK YOU!

First, it seems like there's a slightly undocumented use case for (cond - where the tests don't need to have associated actions. Ok...

The other challenge is I don't see a declaration for TBOX:OFF anywhere in the file. Without asking you to review the actual file from Lee's site, the enclosing function definition is:
Code - Auto/Visual Lisp: [Select]
  1. defun c:tbox ( / *error* box ent enx )

So "tbox" is the function scope...but I don't see anything else for :OFF beyond some other uses. No declarations. Is the (setq valid on it's own without declaring it in the function header? Is it because of the prefix TBOX:?

HeavyThumper

  • Mosquito
  • Posts: 13
Re: Lee Mac's Associative Textbox
« Reply #5 on: July 13, 2021, 05:08:54 PM »
Now I'm getting closer to understanding the basic language syntax - I need to ask about some internals.

This routine is explicitly for MTEXT and TEXT. Can I (simply) modify it to support block attributes as well? Or are the reactor functions that are used not available for such?

If it matters, I would be happy with either, or both, selecting and applying the function to existing blocks or having the associated boxes part of the block definitions. My hope is to change from simple boxes to wipeouts, set to behind the text, to ensure readability of block attributes regardless of other geometry. I have some dynamic blocks with such but I'm looking at replacing them with lisp-based solutions (among other reasons, to more transparently support Bricscad).

HeavyThumper

  • Mosquito
  • Posts: 13
Re: Lee Mac's Associative Textbox
« Reply #6 on: July 13, 2021, 05:18:26 PM »
No sooner do I ask when I come across Lee's AutoLabelAttributesV1-4.lsp.

I'm gonna have some sleepless nights ahead of me...

ronjonp

  • Needs a day job
  • Posts: 7527
Re: Lee Mac's Associative Textbox
« Reply #7 on: July 13, 2021, 05:34:06 PM »
Maybe this helps you understand:

That was huge! THANK YOU!

First, it seems like there's a slightly undocumented use case for (cond - where the tests don't need to have associated actions. Ok...

The other challenge is I don't see a declaration for TBOX:OFF anywhere in the file. Without asking you to review the actual file from Lee's site, the enclosing function definition is:
Code - Auto/Visual Lisp: [Select]
  1. defun c:tbox ( / *error* box ent enx )

So "tbox" is the function scope...but I don't see anything else for :OFF beyond some other uses. No declarations. Is the (setq valid on it's own without declaring it in the function header? Is it because of the prefix TBOX:?
Glad to help :) .. since TBOX:OFF is not included after the / in ( / *error* box ent enx ) that makes it a global variable persistent in the current session.

COND can be used to return the first value it finds .. quick example:
Code - Auto/Visual Lisp: [Select]
  1. (setq var (cond (nil)
  2.                 (nil)
  3.                 (nil)
  4.                 (nil)
  5.                 ("BOOM!")
  6.           )
  7. )

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

Lee Mac

  • Seagull
  • Posts: 12912
  • London, England
Re: Lee Mac's Associative Textbox
« Reply #8 on: July 14, 2021, 05:43:00 PM »
I'm a bit late to the party and the explanations which precede this post cover pretty much everything, but to answer your specific questions:

  • Set a variable tbox:off to the result of a condition. Pause here - where is tbox:off declared? I don't see it in the c:tbox function header.
Indeed, tbox:off is not declared at all: this variable has global scope and is defined within the active document namespace (as opposed to having scope limited to the function in which it is declared). The use of a global variable for this application allows the last used offset factor to be remembered within the active drawing session.

  • Now, reading from the inside out that interesting statement...
  • Initialize tbox:off to 0.35
Correct, but only if tbox:off already holds a non-nil value: if this global variable already holds a non-nil value, the first test expression for the cond statement will yield a non-nil value (and thereby cease evaluation of subsequent test expressions) and such value will be returned by the cond statement.

  • That is then enclosed in parens a second time - because?
Because the setq expression itself forms the cond test expression - it could equivalently be formatted in the following way, which may help you to dissect the various components of the cond expression:
Code - Auto/Visual Lisp: [Select]
  1.     (   tbox:off
  2.     )
  3.     (   (setq tbox:off 0.35)
  4.     )
  5. )

  • Now, test the value of tbox:off - which at this stage I think is undefined
This test is evaluated first, and may yield the value of the tbox:off variable, if the program has already been used in the active drawing session.

  • if it's non-nil - set tbox:off to 0.35. Uh...I'm assuming this is some kind of
    protected initialization but the mechanism escapes me.
The mechanism is essentially equivalent to a basic if statement such as the following:
Code - Auto/Visual Lisp: [Select]
  1. (if (null tbox:off)
  2.     (setq tbox:off 0.35)
  3.     tbox:off
  4. )

  • Now, take the (apparently) numberic result of that conditional, convert to a string, and call (getdist)
The result of the cond expression will always be numeric (unless of course the global variable tbox:off is independently redefined) because if tbox:off is null, it will be assigned the value 0.35, else, it will yield the value assigned on a previous evaluation (which must be numeric given that getdist returns a numeric value).