Get ancestor tags?

I wrote a simple recursive function to get tags of all the ancestors of a record (I tag folders). I’m just curious: is there an easier way than using a function like this to get all the ancestor tags:

use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions

tell application id "DNtp"
	repeat with theRecord in (selection as list)
		set tagList to my getAncestorTags(theRecord)
	end repeat
end tell

on getAncestorTags(theRecord)
	tell application id "DNtp"
		if (exists parent 1 of theRecord) then
			return (tags of theRecord) & my getAncestorTags(parent 1 of theRecord)
		else
			return tags of theRecord
		end if
	end tell
end getAncestorTags

Does that method do what you want? I’m asking because it looks as if taglist is being cleared in every execution of the handler and never set inside it.

In other words: where do you accumulate the parent tags? I’m probably not seeing the obvious.

Sorry, the seond set tagList was a relic from an earlier attempt (I’ve updated the script in the first post). I’m accumulating the tags with the & operator in return (tags of theRecord) & my getAncestorTags(parent 1 of theRecord)

1 Like

Two thoughts coming to my mind:

  1. The function uses only the first parent but records can have multiple parents

  2. I’m not really sure when this function is useful/necessary. E.g. assuming an ordinary tag A has a subtag B and document 1 is tagged with B, then tags of selected record 0 would return A & B.

True - I’ve indeed not included that as I’m not using replicants / duplicates, but that could indeed be added easily.

My motivation for writing this was because I’m using tags with folders and I wanted to get all the tags of the folder structure which theRecord is located in. Suppose the following database folder structure (I’m using indexed folders, but could be imported as well):

-- Resources
   -- Personal Knowledge Management (tag: pkm)
      -- DEVONthink (tag: devonthink)
         -- PDF management (tag: pdf)
             -- theRecord

The script would get the tags for theRecord: pdf, devonthink, pkm.

EDIT: I looking into inheriting tags with folders which would even be more useful for my use case (e.g. when moving theRecord). I thought at first that Group Tags wouldn’t mix with indexed folders, but apparently they do. That might even be more relevant for my use case when thinking a bit more about it.

And inheriting tags of groups would make this function obsolete too.

E.g. by checking which of the parents of a document is an ordinary tag. These are the tags directly assigned to the document (assuming that’s what you call your own tags).

It looks as if you’re replicating information from the group (not folder) name as a tag. Out of couriosity: Why is that necessary? Or rather: what does the tag “pkm” tell you that “Personal Knowledge Management” doesn’t?

I can see the point of these tags if they occur in another context, too, e.g. in another parent group. But looking at your example, I think that you’re perhaps building a hierarchy that is too deep.

Personally, I go the other way round: Collect stuff in a single group until it becomes to large. Then I split it up into one or more groups. Tags inside a group help to further differentiate. But that’s just me, of course.

Agreed @chrillek - the approach could be better. The starting point was that I was using descriptive folder names ('Personal Knowledge Management) while the tag was more terse and couldn’t contain spaces (pkm) for use in other tools such as Obsidian.

I like my items not to be in a single folder because I like to have some structure in my Finder as well (and the most of my items fit fine inside a singular tag hierarchy). After better understanding Group Tags I’ve updated the structure to be basically tags.

-- Resources
   -- pkm
      -- devonthink
         -- pdf
             -- theRecord

And by using Exclude Groups From Tagging to false I’ve got most of what I was after I think.

So you’re using indexed items rather than imported ones. That explains a lot. I’m importing everything, so don’t care for Finder.

Trying to do this I have this:

tell application id "DNtp"
	repeat with theRecord in (selection as list)
		set allTags to (tags of theRecord)
		set ownTags to (name of parents of theRecord whose tag type is ordinary tag)
		set inheritedTags to (name of parents of theRecord whose tag type is group tag)
	end repeat
end tell

This only gives me the inherited tags from the direct parent. Is there a way to only get the inherited tags? I could ofcourse just remove ownTags from allTags, but is there a better way (besides resorting to my original recursive function)

The inherited ones are all tags minus the own tags.