Using a note to store and set action code elsewhere

This simple trick makes it easy to write and maintain longer pieces of action code - especially where too long to fit in input boxes on a note's Rename dialog. In addition, use of the built-in 'Code' prototype makes layout of code much more easy.

The basic principle involves writing code in the $Text of a note and then using the same note's $Rule to set the a $Rule or $OnAdd in some other note. by the same means an agent query or action can be set.

Add the built-in Code prototype

Add the built-in Code prototype

If not already in the Tinderbox document, use File menu -> Built-In Prototypes... and click Code in the sub-menu.

The new Prototype is inserted

The new Prototype is inserted

If not already present, Tinderbox will create a 'Prototypes' container at root level and insert the 'Code' prototype. If a 'Prototypes' container already exists (a root level or below), the new prototype will be added to that. If more than one 'Prototypes' container is found, the first in $Out;lineOrder is used. The Code prototype modifies a note thus:

  • $Badge is 'design'.
  • $Color of 'lightest black'.
  • HTML paragraph and first/indented paragraph start/end values are set to nothing.
  • $HTMLDontExport is set to true (i.e. by default code notes don't export).
  • $ParagraphSpacing is 0.
  • $TextFont is set to a monospaced font 'Andale Mono'.
  • $TextSidebar is set to false.
  • $AutomaticIndent is set to false.
  • $NoSpelling is set to true.

These settings, as will be shown later below, make for a more 'code-like' display. The monospace font ensure all characters are the same width making it much easier to see things like unintended white space being left in code. For instance the difference between "some text" and some text" is much clearer in a monospaced form:

"some text" and some  text"

The double-space in the later is more apparent.

Add a Codes container

Add a Codes container

You could just add notes anywhere and set their $Prototype to 'Code', but if setting up from new, a good idea is to add a 'Codes' container alongside your 'Prototypes' .

Configuring the Codes container

Configuring the Codes container

Via the Rename dialog, set the container's $OnAdd action:

$Prototype="Code";

Also, set $HTMLDontExport to true and $HTMLExportChildren to false. Thus neither the container nor its children will get exported is HTML export is used (likely what you'll want).

Add a target note for the code note

Add a target note for the code note

This is really only needed for the demo. In a real scenario, likely this note already exists. Select 'Codes' and press Return to make a new sibling note. Title the note "Complex Task".

Add a new code note to the Codes container

Add a new code note to the Codes container

Select the 'Codes' container and press Shift+Return to create a new child note. Notice how the desired prototype is automatically applied. You can call the note whatever you like but a good tip is to use a name that makes it self-evident this is a code note. Name your new note "cComplex_Task", reminding you this note if for the note "Complex Task". Don't feel obliged to follow such direct naming - use whatever suits you.

Add some code to the code note $Text

Add some code to the code note $Text

Add this to $Text:

if($ChildCount) {
    $Color="bright blue";
    $DisplayExpression='$Name+" ["+$ChildCount+"]"';
} else {
    $Color=;
    $DisplayExpression=;
}


As you can see this is far more code than you can easily fit in a note's Rename dialog $Rule box, plus you'd need to ender the code with out any nice formatting like line breaks and indented conditional branches.

What does this do? If the note running the rule has any children, the note is coloured bright blue and its display expression shows its child count in square braces after the $Name. When there are no children both those attributes are reset to default values (that is the =; trick - see more)

Connect the code note to its target

Connect the code note to its target

In the code note's $Rule box type this:

$Rule("Complex Task") = $Text;

Review the rule of the target note

Review the rule of the target note

Notice that, apart for line-wrapping, the source format is retained and is not all visible in the normal input box.

Try out the new rule - 1

Try out the new rule - 1

Select 'complex Task' and Shift+Return to add a child note - any name will do. See how the rule is used.

Try out the new rule - 2

Try out the new rule - 2

Now delete the new child and see how the rule resets the affected attributes.

Making changes to the live rule

Making changes to the live rule

In the code note, the $Text to the following. The change is the $Color line in the 'else' condition.


if($ChildCount) {
    $Color="bright blue";
    $DisplayExpression='$Name+" ["+$ChildCount+"]"';
} else {
    $Color="bright red";
    $DisplayExpression=;
}

Now, when the note has no children, the child count isn't shown and the note is bright red.

The target note is automatically updated

The target note is automatically updated

Sure enough, as 'Complex Task' has no children it now colours bright red. But, add back a child…

Test the other condition again

Test the other condition again

Sure enough, the note is now blue and has a display expression.

Affect more than one note - work with prototypes - 1

Affect more than one note - work with prototypes - 1

Delete the child note just added. Move 'complex Task' into the 'Prototypes' container. Doing so makes it a prototype; if using your own 'Prototypes' container without the $OnAdd, open the note's Rename dialog and tick the Prototype box.

Affect more than one note - work with prototypes - 2

Affect more than one note - work with prototypes - 2

Select 'Complex Task' and open the Inspector using the Window menu or press Cmd+1. Set it as below

  1. In the left Attribute pop-up, select General.
  2. In the right Attribute pop-up, select RuleDisabled.
  3. In the Value box type true (all lowercase, case-sensitive).
  4. Click Apply.

Affect more than one note - work with prototypes - 3

Affect more than one note - work with prototypes - 3

One more task. Now the rule is disabled in the prototype, we need to rest $Color as it's currently been set at note level.

  1. In the left Attribute pop-up, select General.
  2. In the right Attribute pop-up, select RuleDisabled.
  3. Click the use default button.

Affect more than one note - work with prototypes - 4

Affect more than one note - work with prototypes - 4

The result is the rule is suppressed - but only in the (current) prototype note, which resumes normal color.

Note that the last step would not have been necessary if starting with a new prototype note.

Testing the new Prototype - 1

Testing the new Prototype - 1

Add a new note, and right-click the icon to the left of the note. From the pop-up prototype list, select Complex Task.

Now add a second note, with child notes, and apply the same prototype.

Testing the new Prototype - 2

Testing the new Prototype - 2

Notice how the rule, stored in the code note, is setting the prototype's $Rule which is then inherited and used by notes using that prototype.

Hopefully this latter stage helps demonstrate how easy it is to write the code once, in a layout that lets the code be seen in unambiguous form, and yet can affect many notes. Not only that, but changes made to the code note effect instant change on the notes using it.

Don't forget agents

Above, you've used notes. However you could as easily use a code note to the the query ($AgentQuery), action ($AgentAction) or rule ($Rule) of an agent.

Still not clear?

If unsure on the procedure, read the Tinderbox manual and see aTbRef. If still unsure contact Tinderbox tech support or ask in the Tinderbox User-to-User forums.