Tinderbox Forum

Changing the appearance of notes (same prototype) depending on displayed attribute

I have a bunch of reference notes, imported from Bookends, and I want to change their appearance to be able to distinguish them more quickly. They are essentially three types, namely BOOK, CHAP and JOUR. These designators are held in the displayed attribute $RefType.

Where do I do so? I first thought I could give the prototype (all these notes are of prototype pReference) an edict that would go as follows:

if($RefType="JOUR"){$Color="green";$AccentColor="green;$Badge="Journal-512";};if($RefType="CHAP"){$Color="red";$AccentColor="red";$Badge="Book-chapter-512";};

However, nothing happens if I do that. And putting a rule of the same content into the prototype also has no effect on the notes.

Putting the same code into a stamp has no effect either. So I am a bit puzzled - is there an error in my code, or do I put it in the wrong place? I’d be grateful for any guidance!

This is the error:

$AccentColor="green;

Notice the lack of closing quotes? There are also two other syntax errors, but which Tinderbox manages to figure out.

  • = mean make the value of the left side the value of the right side
  • == are the left side and the right side exactly the same (true/false?)

In case like your code Tinderbox normally guess you meant = and acts accordingly, but it’s best not to force the app to guess when you know the test you are trying to apply.

So, working code (tested in a stamp in v8.9.2) is below. I’ve added line breaks for clarity (but these are ignored when the code is run):

if($RefType=="JOUR"){
	$Color="green";
	$AccentColor="green";
	$Badge="Journal-512";
};
if($RefType=="CHAP"){
	$Color="red";
	$AccentColor="red";
	$Badge="Book-chapter-512";
};

I assume you are using two discrete if() tests because there are other $RefType values. As the attribute is a string, a note only has a single value or no value. Thus if there were a note with no $RefType value and one with the value “BOOK” they will match neither test and unaffected by the above code.


How I did the de-bugging:

  1. I took your code, made a test doc and tried your code as a stamp. As described it failed.

  2. scanning the code in the Stamp code box I spotted the = vs. == error right away but fixing that had no effect.

  3. So I copied the code into a plaintext editor: I used BBEdit but you can use similar or a note $Text in a note set to use the “Code” built-in prototype.

  4. I then laid our the code above, looking for missing parentheses, curly brackets or semi-colons (next hunch!). They were fine but I did spot the missing closing double-quote.

It’s a fairly easy process. Had that failed, the next part os to make a smaller test, perhaps using only one if() test at a time, re-testing iteratively to try and se what fails (or in this case when it starts working. At that point the last thing removed or altered was the error.

Mark, many thanks for the answer and for making such an effort to solve my problem! I much appreciate it.
In retrospect such a simple error, but since you also overlooked it first, I do not feel too bad about it. By the way, do you think it is possible to produce a language file for BBEdit that would help spot such errors? It seems that many in the Tinderbox community use BBEdit, so there might be some use for that.
Indeed the logic of the two if questions is as you assume. There is a BOOK value as well, but in that case I want the appearance of the note not to change from the standard of the prototype.
A last question: where would I best run such code? Is my hunch that (since it will hardly change) an edict in the prototype is the best place? Or would you advise something else?
Many thanks again for your help!

Using PHP as language works fine in BBEdit. Thanks btw @bmscmoreira!

1 Like

TL;DR It’s complicated :slight_smile:

As described in a current meet up, syntax colouring is coming to some codes spaces in Tinderbox 9.

A problem with the syntax is much of it is optional and extensible whilst at the same time lightly documented. My own aTbRef notes are under constant change as we discover that something is more—or less—flexible in parsing input than we imagined. Export code was originally conceived for HTML export of blogging and there used to be a separated #-prefixed 'code method for queries. The latter and much of the former have ben subsumed into Action code which started out as a very permissive coding style following the concept of things like AppleScript. IOW, you write what makes sense and the computer figures it out.

In fact, as hubristic failures in Machine Learning have shown, human writing is hard to parse for meaning, even without typos—rather in the way it is said that the English language is defined by the exceptions to its rules.

So, whilst one could write a plugin for BBEdit or such, my sense as a long time user and documenter of the app is that we don’t have accurate enough underlying statements of design intent to write a reliable parser while both correctly captures code terms and matches Tinderbox’s, err, ‘flexibility’ in interpretation of input. I’d note many of the conventions or ‘rules’ in my documentation are my own additions to avoid learners being faced with a learning scenario of “type what you want, it may work or it may not”. Even after quite deep use of the app for 17 years, I still trip over limitations that have never—to my knowledge—ever been described and can’t easily be guessed.

Please don’t be tempted to read the latter as criticism. Rather it is a statement of fact. Action code wasn’t added as a deliberate ‘full’ coding environment. Instead, it grew out of simple macros and has been growing ever since, in response to user’s requests. It also services an open-ended toolbox meaning have all sort of potential combinations in which to give the app things it never really expected by way of code.

For instance, this could be legal code:

$MyString='"green';

Quite why one might want a string value of "green is a separate question (though I can probably think of some).

†. Whether it is just the Action Inspector, or other places like Displayed Attributes or stamps in the Inspector is yet to be decided.

1 Like

Thanks - I appreciate the historical background. It seems Tinderbox action code underwent a process of increasing formalisation itself :wink: And indeed future syntax colouring may help. If I were ever to try longer pieces of code it looks like the idea of using the PHP language file in BBEdit would indeed work well - thanks to Pete for that hint!
Can I come back to my question of where to put the code in question best?

Is there any advice you could give? I found that putting it into an Edict, even if I clicked the “run now” box did not do much. Once I had it in there, however, any clicking of a note in the container that held them would result in the note being given the treatment given in the Edict. So I had some fun clicking them all (some 80), but for future use I may want a less time profligate way of proceeding…

In my opinion, this task is classic Agent territory.

First, it breaks down nicely into two parts:

  1. Which notes shall we change? (Those for which $RefType="JOUR")
  2. What shall we change? (Make these green)

This is what agents do.

Interesting - thank you!
My thought was that this would waste computing power since this would likely only have to be done once (because a publication is either this, that or the other), hence not a task that needs repeating. Also, so far I mainly used agents to produce something in a container that I could use further, but that is probably an unnecessary limitation. And letting it be done by an agent means that it gets done quickly.

Further to the last, you can make the agent run at a low priority or switch it off when not needed.

I assume this was the initial 80. Are you adding 80 such notes every day? Then I’d go an agent route. If it is one or two every now and then, I’d probably use a stamp. When adding automation like this don’t confuse the one-off task of updating any pre-existing notes with the workflow of adding new ones.

How you run the code rather depends on your task’s needs:

  • Frequency. How often do you need the action to run, or a condition tested in order to decide if an action should be run? N.B. this is discrete from any one-off task to update existing notes.
  • Scope. Does the code need to run on all notes or only some on all notes?