Get a list of user generated attributes

Is there a way to produce a list of usr-generated attributes in a TBX file without using Apple Script?

See Dictionary["key"], especially the key user-attributes. Also, once you know an attribute’s name you can find further details via attribute("attributeName")["key"].

So:

var:list vAttributes = document["user-attributes"];
var:list vKeys;
var:string vOutput;
vAttributes.each(anAttribute){
	vOutput += "----------\n" + anAttribute + "\n" +"----------\n";
	vKeys = attribute(anAttribute).keys;
	vKeys.each(aKey){
		vOutput += aKey + ": " + attribute(anAttribute)[aKey] + "\n";
	};
};
$Text = vOutput;

Works for me in v9.3.0 (above code code just added to attribute() operator page)

1 Like

Hi MarkA,

Thank you for the code. Would it be possible for you to comment the code above.

Thanks
Tom

Sure, there are some gremlins in comments (already reported by me to @eastgate) that cause the code to not execute do do not copy/paste the commented code below but use the uncommented one below. I’ve also just added code to:

  • report the filename of the document
  • report the overall number of user attributes
  • filter out the ‘category’ key as all attributes here are in the User group.
  • filter out empty keys. This also helps indicate things that could/should have a value, e.g Description.
// AIM: report a TBX document's user attributes and their settings
// pre-make variables
var:list vKeys;
var:string vOutput;
// make a list variable and collect the names of all current user attributes of front doc
var:list vAttributes = document["user-attributes"];
// report the document name and number of user attributes
vOutput += "TBX filename " + document[name] + "\n";
vOutput += "Number of  user attributes: " + vAttributes.count + "\n--------------------\n";
// iterate the list of user variables
vAttributes.each(anAttribute){
	// for each discrete user attribute
	// store the attribute name between lines of 
	// hyphens (old-school plain-text horizontal rules
	vOutput += "--------------------\n" + anAttribute + "\n" +"----------\n";
	// set a variable to the dictionary of the current attribute's features
	vKeys = attribute(anAttribute).keys;
	// iterate those features
	vKeys.each(aKey){
		// for each feature store the feature's name colon+space feature value
		vOutput += aKey + ": " + attribute(anAttribute)[aKey] + "\n";
	};
	vKeys.each(aKey){
		// for each key test is it not 'category' and that it has a value
		// comment out the if() line and closing curly bracket line to get all keys, regardless
		if(attribute(anAttribute)[aKey] != "" & aKey != "category"){
			// for each feature store the feature's name colon+space feature value
			vOutput += aKey + ": " + attribute(anAttribute)[aKey] + "\n";
		};
	};
};
// set the note's $Text to the stored list  
$Text = vOutput;

Here is an uncommented version of the above for copy paste:

var:list vKeys;
var:string vOutput;
var:list vAttributes = document["user-attributes"];
vOutput += "TBX filename " + document[name] + "\n";
vOutput += "Number of  user attributes: " + vAttributes.count + "\n--------------------\n";
vAttributes.each(anAttribute){
	vOutput += "--------------------\n" + anAttribute + "\n" +"----------\n";
	vKeys = attribute(anAttribute).keys;
	vKeys.each(aKey){
		if(attribute(anAttribute)[aKey] != "" & aKey != "category"){
			vOutput += aKey + ": " + attribute(anAttribute)[aKey] + "\n";
		};
	};
};
$Text = vOutput;

You don’t have to pass `vOutput to a note $Text: that is just easiest fro quick test. You might for instance pass the content to a run command to generate an external text file and thus a report. I leave such extensions as an exercise to the user.

I’ve put this version in aTbRef shortly - see attribute("attributeName")["key"]. Usefully in testing for this post, I found and fixed a number of typos in the aTbRef TBX’s user attribute descriptions, so proof of purpose!

†. For those worried about this, I think the issue is an edge case where either/both:

  • there is a comment in the first line of the action
  • the comment text uses a single (or odd number) of single quotes used as normal apostrophes for possessive terms, e.g. “Tom’s” as in // This is Tom's great new action

so losing such apostrophe’s may help if you really want comments here in the short term, but for me the resulting bad grammar is a stab in the eye. YMMV, we all read in different ways. :slight_smile:

4 Likes