Tinderbox User-to-User Forum (for formal tech support please email: info@eastgate.com)
Tinderbox Users >> Agent, Actions, Rules & Automation >> Help with Sets

Message started by Allen Mikaelian on Sep 20th, 2016, 11:10am

Title: Help with Sets
Post by Allen Mikaelian on Sep 20th, 2016, 11:10am

Hi, new to Tinderbox, as evidenced by the really basic question below. I've been fairly successful creating actions that assign or manipulate values, but working with sets seems to be very different.

I'd like to have an agent or container that displays a list of unique values in $Tags. It would be useful to keep track of tags used in a document or in a specific container.

I've messed around with collect(group,attribute), but List/Set.each() sounds even more promising because its description in the acrobatfaq includes the following example:

$MyList.each(x){ $Result=$Result +x+"\n" ; }

will replace the text of the note with a list of values of $MyList, each on its own line.

And this sounds ideal, but my attempts to adapt that example to my own document have failed so far. In many attempts $Text is merely changed to "each" so I'm clearly missing something here....

I'm guessing there's a simple explanation so I won't bore you all with all the things I tried. And I'm also open to other approaches.


Title: Re: Help with Sets
Post by Mark Bernstein on Sep 20th, 2016, 11:53am

Let’s start with simply getting the list of tags. Later, we’ll make it pretty.

A list of all the discrete values used by a list or set attribute can be generated by the values() operator.


returns a list of all the tags currently in use in the document.  (Note that the argument is the name of the attribute as a string. ). So the rule

     $MySet = values("Tags")

will place a list of values into the $MySet attribute of this note, and

    $Text = values("Tags")

will place a list of those values in the note’s text. (Note that the text won't change while you're editing it; you'll need to deselect and reselect the note to see the change.)

Now, suppose we want know only the tags applied to notes inside a specific container named box.  We need something like this:

    Rule: $MySet=collect( ....some notes.... , $Tags)

collect() has two arguments; the first determines which notes we want to examine, and the second specifies what we want to collect from each note.  Which notes do we want?  We want the children of the top-level note named "box".


And so our Rule is

         Rule: $MySet=collect(children(/box) , $Tags)

Remember: Set attributes automatically remove duplicates.

Title: Re: Help with Sets
Post by Mark Anderson on Sep 20th, 2016, 12:09pm

If you want the list in $Text in a more readable, sorted, one item per line/paragraph form, that's easy too:

$Text = values("Tags").sort.format("\n")

If you do this, I'd suggest not leaving to to run all the lime. You can always leave the rule code in place and un-tick the 'enabled' box on the note's rule inspector to stop it running.

You can do the same with the collect example but you need an extra step because collect() returns a List-type and not a Set-type. The two primary differences ofList and sets is Sets don't allow duplicate values (so a List may contain them) and Set don't (necessarily) hold a sort order. So to get a de-duped result via collect - using Mark B's example:

$Text=collect(children(/box) ,$Tags).unique.sort.format("\n")

Extra Tip...

Once you've got a list of all your tags, in $Text, you can explode that note and you'll have a note for each discrete value in the list. Just be aware is the source list changes the exploded note list is out of data and do watch for making notes that might have the same name as an existing note.  this technique is very good for things like extracting a list of all the discrete authors in $Authors for a set of papers and then writing per author notes. You can also link the author notes to their papers etc. Action code can do that do, but that's something for a different thread (if interested).

Title: Re: Help with Sets
Post by Allen Mikaelian on Sep 20th, 2016, 4:52pm

Perfect, just perfect. Got it to work and I'm all set.

And thanks for the extra tip about exploding the note. Each exploded note can, I'm thinking, get an AddOn action that will append a tag to a new note that I drag into it. So: drag-and-drop tagging of new notes based on an already existing set of tags. :D Nice, if I can make that work, and I'll check back if I can't.

Many thanks,

Title: Re: Help with Sets
Post by Mark Anderson on Sep 20th, 2016, 5:06pm

Yes, and if you prefer to work on a map don't forget adornment have an $OnAdd to so you can use adornments as value-setters, drag-drop a note onto an adornment firing its OnAdd then drag it back elsewhere - job done.

FWIW, once you've done your explode and checked all is desired I usually find it pays to move all the new notes up a level (or somewhere else completely if needs be) and bit the 'exploded notes' container. That way when you do a different explode the new container's easier to find. But do initial checks first, another boon of the 'exploded notes' container is that if your explode doesn't work as expected you can just delete that container, fix the source and try over. Also, if exploding large amounts of text for a note it's a good idea to delete that text when done. TB's happier opening/traversing notes with smaller amounts of text: IOW don't keep big notes unless you really mean to (in the excitement of the moment these clean-up issues are easy to overlook),.

Tinderbox User-to-User Forum (for formal tech support please email: info@eastgate.com) » Powered by YaBB 2.2.1!
YaBB © 2000-2008. All Rights Reserved.