How would I go about writing an action code that will give me a list of every attribute that has a non-default value for a given note? Let’s say we put the result in the $Text of a note.
I tried to write an action code that lists attributes with different default values.
I hope it matches what you want to do.
function fGetAttributeList(){
var:list vKeys;
var:string vOutput;
var:string vLeft;
var:string vRight;
$Text =;
vKeys = $MySet("System Attributes");
vKeys.each(aKey){
vLeft = eval("$"+aKey);
vLeft = vLeft.replace("\n","");
vRight = attribute(aKey)["default"];
vRight = vRight.replace("\n","");
if(vLeft != vRight){
// vOutput += aKey + ":" + eval("$"+aKey) +"⬅️" + attribute(aKey)["default"] + "\n";
vOutput += aKey + "\n";
};
};
$Text = "-----System Attribute\n";
$Text += vOutput;
vOutput="";
vKeys = document["user-attributes"];
vKeys.each(aKey){
vLeft = eval("$"+aKey);
vLeft = vLeft.replace("\n","");
vRight = attribute(aKey)["default"];
vRight = vRight.replace("\n","");
if(vLeft != vRight){
// vOutput += aKey + ":" + eval("$"+aKey) +"⬅️" + attribute(aKey)["default"] + "\n";
vOutput += aKey + "\n";
};
};
$Text += "\n-----User Attribute\n";
$Text += vOutput;
};
(The “replace” function may not be necessary for comparisons.)
AttributeList_without_default_value.tbx (447.4 KB)
Here’s an external script for comparison. It collects attributes of the selected note whose values are not default and places their names and values on the clipboard for pasting wherever.
tell front document of application "Tinderbox 9"
set outputStr to ""
repeat with anAttribute in attributes of selected note
tell anAttribute to if value is not defaultValue then set outputStr to outputStr & name & ": " & value & return
end repeat
end tell
set the clipboard to outputStr
return outputStr -- line optional, to view in result panel
This is GREAT. Really clean. Lots of ways to modify it. Thanks.
I am happy to be of assistance.
If you want to find which (system) attributes in a document use non default values as per the currently open version of Tinderbox:
tell front document of application "Tinderbox 9"
set outputStr to ""
repeat with anAttribute in attributes
tell anAttribute to if value is not defaultValue then set outputStr to outputStr & category & ": $" & name & ": " & value & return
end repeat
end tell
set the clipboard to outputStr
return outputStr -- line optional, to view in result panel
Notice in the repeat
line the ‘selected note’ address is dropped (from the exam[le further above) so we are now reading the doc level values/defaults. I’ve also pre-pended the attribute’s category (Tinderbox attribute group) and a ‘$’ so you get output like:
Events: $TimelineScaleColor2: #f2f2ed
General: $ChildCount: 12
General: $Created: 2010-01-12T09:23:07Z
General: $DescendantCount: 108
General: $DisplayName: Starter_8-5
General: $ID: 1697187039
General: $IDString: tbx:BlKQTf
General: $InboundLinkCount: 1
General: $Modified: 2012-02-15T17:04:00Z
General: $Name: Starter_8-5
General: $Path: /
General: $SelectionCount: 17
General: $SiblingOrder: 1
HTML: $HTMLExportPath: /.html
Net: $NoteURL: tinderbox://?view=outline+select=1697187039
TextFormat: $TextAlign: left
Textual: $EstimatedNoteSize: 11
But why values like a $ChildCount of 11? This is because the attribute is calculated … and the root of the outline has 11 items!. Still, this does show that $TimelineScaleColor2 and $TextAlign have non-default values. BTW, the $Created/Modified dates as those of the outline root level item (not seen in the app) in the XML. This doc was made via the old ‘favourites’ method, i.e. a copy open then saved. I do wonder if doing an explicit ‘Save As’ (Cmd+Opt+Shift+S) might be a better option today.
Sadly, the AppleScript method doesn’t expose whether an attribute is read-only, so we can’t filter those out while scripting without manually making a look-up list of attributes to ignore.
Staying in Tinderbox, currently there is no means to read system attribute names via action code. The document() operator only lists user attributes. But if we had a list of all attributes, attribute() can interrogate any attribute as long as it knows the names. Sadly, attribute()
doesn’t reveal is an attribute is read-only. This does make sense as the operator(), as at present, was envisaged primarily for use with user attributes or system ones that are editable.
This AppleScript will list all attributes in the document (filter for category not being ‘user’ to leave out user attributes):
tell front document of application "Tinderbox 9"
set outputStr to ""
repeat with anAttribute in attributes
tell anAttribute to set outputStr to outputStr & name & return
end repeat
end tell
set the clipboard to outputStr
Helpfully the attributes list A-Z by group and A-Z within group, i.e. the list starts with the ‘AI’ system group, with `DominantLanguage’ being the first item in that group. If you want to remove calculated attributes from the overall list, luckily aTbRef a list of such attributes here.
So non-quite a one click solution but was can do much of it with the various scripts offered in this thread.
On the theory that when it comes to AppleScript with its “flexible” documentation there can never be too many working examples to study, here are some more building on ideas raised by @mwra .
- This one will retrieve attributes not in an exclude list:
property excludeAttribs : {"AdornmentCount", "Aliases", "ChildCount", "Created", "Creator", "DescendantCount", "DisplayName", "EstimatedNoteSize", "ID", "IDString", "ImageCount", "InboundLinkCount", "IsAdornment", "IsAgent", "IsAlias", "LastFetched", "LocalAttributes", "Modified", "OutboundLinkCount", "OutlineDepth", "OutlineOrder", "Path", "PlainLinkCount", "ReadCount", "SelectionCount", "SiblingOrder", "TextLength", "TextLinkCount", "WebLinkCount", "WordCount"}
tell front document of application "Tinderbox 9"
set outputStr to ""
repeat with anAttribute in attributes
tell anAttribute to if value is not defaultValue and name is not in excludeAttribs then set outputStr to outputStr & category & ": $" & name & ": " & value & return
end repeat
end tell
set the clipboard to outputStr
return outputStr -- line optional, to view in result panel
Just set up an exclude list and add is not in
to the conditional.
But that script, like the scripts above, is slow.
For much faster results, at the expense of somewhat harder to understand code, take advantage of how efficiently Tinderbox can place values into AppleScript list(s). Then iterate through the AppleScript lists instead retrieving them one by one from Tinderbox.
- This one uses that approach get the names of all the attributes in the front document:
-- populate an AppleScript List with attribute names
tell front document of application "Tinderbox 9" to set attrNames to name of attributes
-- convert the AppleScript List to a string
set text item delimiters to return
set the clipboard to attrNames as string
return attrNames as string -- line optional, to view in result pane
- And to list category, attribute name, value, and default value (type is also accessible) of attributes not in an exclude list:
property excludeAttribs : {"AdornmentCount", "Aliases", "ChildCount", "Created", "Creator", "DescendantCount", "DisplayName", "EstimatedNoteSize", "ID", "IDString", "ImageCount", "InboundLinkCount", "IsAdornment", "IsAgent", "IsAlias", "LastFetched", "LocalAttributes", "Modified", "OutboundLinkCount", "OutlineDepth", "OutlineOrder", "Path", "PlainLinkCount", "ReadCount", "SelectionCount", "SiblingOrder", "TextLength", "TextLinkCount", "WebLinkCount", "WordCount"}
-- place properties of attributes into three AppleScript lists
tell front document of application "Tinderbox 9" to tell attributes
set {attrCategories, attrNames, attrValues, attrDefValues} to {category, name, value, defaultValue}
end tell
-- build output string from the three lists using an index
set outputStr to ""
repeat with i from 1 to length of attrNames
if item i of attrNames is not in excludeAttribs and item i of attrValues is not item i of attrDefValues then
set outputStr to outputStr & item i of attrCategories & " : " & item i of attrNames & " : " & item i of attrValues & " : " & item i of attrDefValues & return
end if
end repeat
set the clipboard to outputStr
return outputStr -- line optional, to review in result panel
Note that local attributes
and user attributes
are in the AppleScript dictionary for Tinderbox 9.
- So to get a list of the names of all
user attributes
in the document:
tell front document of application "Tinderbox 9" to set attrNames to name of user attributes
-- convert the AppleScript List to a string
set text item delimiters to return
set the clipboard to attrNames as string
return attrNames as string -- line optional, to view in result pane
I'm hazy on when, if ever, one might want to use `local attributes` in a script, or how to access them from AppleScript. The above script doesn't work if you simply substitute `local attributes` for `user attributes`.
Delving further with AppleScript Debugger, I misspoke before. The AppleScript doc-scope attributes
objects actually all/only the (app’s) system attributes. The document’s user attributes are accessed via the document scope user attributes
object.
Although local attributes
are a note-level object and they only have a meaning when interrogated at note scope. local attributes
includes any attribute system or user that has a value that has neither a default nor inherited (non-default) value.
Ah yes, note-level so this works to list the local attributes of a selected note:
tell front document of application "Tinderbox 9"
set outputStr to ""
repeat with anAttribute in local attributes of selected note
tell anAttribute to set outputStr to outputStr & name & " : " & its type & " : " & value & return
end repeat
end tell
set the clipboard to outputStr
return outputStr -- line optional, to view in result panel