For any given note, which attribute values differ from the defaults?
For each non-default value, what is the source? Are they set on the note itself or are they inherited? If the latter, what is the path of inheritance?
It would be useful if Tinderbox could answer these questions for me. A couple of use cases:
I’ve made some changes to the attributes of this note and would like to copy them to its prototype. Remind me what I’ve done to this note’s attributes.
I’d like to understand what this built-in prototype does. Show me the attributes that make it special.
Unless you use cascading prototypes—allowed but rarely encountered—the inheritance chain of attribute default values is this:
document default, as seen in the Document Inspector:system tab or in some cases this default is set in Document Settings.
prototype. $Prototype.
current note.
So, this is no one-shot solution here. However, hasLocalValue() covers the local scope (bullet #2). Checking the same attribute the note given in $Prototype, if any, for hasLocalValue() will tell you if the prototype note has a local due for that attribute (bullet #2).
So I think this is not complex for check … unless you’ve some byzantine nested prototype set-up.
This is less easy. hasLocalValue() is scoped to a single attribute, but there are >400 system attributes plus and user attributes which might be another 100.
What you need perhaps is a non-existenthasLocalValues(scope) operator that for the given note tells you all the system or user attributes that have a non-default value.
Are you suggesting that I try to write some action code that iterates though all attribute names, filter with hasLocalValue(), and put formatted results somewhere? Or is that not possible at the moment? (I don’t see a way to get a list of all attribute names.)
Hmm. There are over 400 system attributes plus whatever user ones you added. If you’re happy doing action code you also have all you need. If not confident with action code, I’d open Get Info:attributes then select each attribute group in turn and note the names of any attribute name in bold text. The latter indicates that the attribute has a local value.
Want to know what is set in the prototype (as opposed to a note using it, select the prototype and use getInfo.
An operator to ‘just’ do this doesn’t exist and I don’t think anyone has requested such. You could always email in a request to the developer (here is not the place for such direct feature requests, as we’re fellow users). Per later comment, see $LocalAttributes.
I should point out than whilst the document() operator’s user-attributes key gives a list of all currently defined user attributes of the active document, there is such method for all system attributes. But these can either be extracted from the XML of the TBX file or from aTbRef’s various listings.
External scripts (AppleScript/JXA) can do this. In looking at old scripts I stumbled on $LocalAttributes, which allows a stamp something like this to produce answers to some of these questions:
Go to Stamp > Inspect Stamps, create new stamp, and paste in this code. Then select a note and run from Stamps menu to see non-default values of attributes. As written the results are placed in a note named “Log” at root level (the note is created if it does not already exist).
For the built-in Markdown prototype the results look like this on my machine:
// Format output for showLocals().
function formatAttribute(x) {
return x + ": " + eval(x) + " << " + $Prototype + ": " + eval($Prototype, x) + " << default: " + attribute(x)["default"];
}
// Inspect a note's local variables. Try command-shift-u and `/eval showLocals()`
function showLocals() {
return $LocalAttributes.sort().collect(x, formatAttribute(x)).format("\n");
}
I had no idea cascading prototypes were rarely used. I use them: like a note “my fun party” will have Prototype=“FunEvent,” which has Prototype=“Event”. But I don’t think it’s worth complicating these functions to walk the inheritance chain for me because they’re pretty easy to follow.
It turns out that this thread wasn’t so “off the wall” after all. Should it be recategorized to “Tinderbox Tasks,” do you think?
I think the listing allows up 3 since of content (or title+ 2 lines of explanation), which is what the linked article’s screen grab shows. The result panel extends to a certain size and then offers scroll bars for the item list if there are too many items to fit in.
In your example, the list appears truncated as there is only one match item to the input ‘query’. However, you can’t see more content about the showLocal() item beyond the 3 lines shown. The idea of the Command Bar is to find items not as a full reference document.
I’d try swapping out ; for ,. Obvs, this is OK for numerical data like $Tabs. Might not be so good if list items may contain a comma.
To do that via action code with a String type output, try this ($Text there so some left side element for clarity) to give a comma+space delimiter in output:
$Text = $Tabs.replace(";",", ");
Takes raw List value of:
0.25;0.25;0.25;0.25;
and gives:
0.25, 0.25, 0.25, 0.25,
Note the trailing comma: if that offences the eye you can test for it and remove:
Yeah, I couldn’t make much headway improving the list/set formatting in those functions. I don’t quite understand what eval is returning or exactly how string formatting is happening. (eval is the appropriate call to get an attribute value using an attribute name string?).
I notice that
/eval eval(Tags)
presents newline-delimited results, whereas
/eval eval("Tags")
presents semicolon-delimited results. But I’m not sure how to interpret that.
Also
/eval type(eval(Tags))
returns nothing, which I don’t understand. So I think I’ve reached the limits of being useful here.