How to automatically create aliases w/in containers from titles & hashtags?

Hi, I asked this questions in another thread, but it seems more appropriate to perhaps start another thread with this singular question.

Here’s my situation… I port over MarginNote-created containers and notes into Tinderbox (via iThoughtsX). Within Tinderbox, the containers are titled with subject categories, and notes have titles that identify subcategory, or subcategories, MarginNote-created annotated text, as well as hashtags (e.g., for task, such as questions, research, reading, etc.) that appears in Tinderbox’s text pane, and a link back to the the original text (in MargninNote) in Tinderbox’s url section.

In many cases, I include 2 - 3 titles (i.e., subcategories) for my MarginNote-created notes, since certain discrete annotations might fall into multiple subcategories (as replicants in DEVONthink or aliases in Tinderbox). Ditto that with hashtags that carry over from MarginNote to Tinderbox.

So… What’s the best way (perhaps through Actions or Agents) to automatically have these titles create aliases to (or within) their respective associated Tinderbox containers? Thanks!

Although you want to auto-create aliases (something not actually possible via action code**) there is some structural data missing from your description. The titles of all descendants of any category container note contain one or more subcategories in their title ($Name). But, how are the individual subcategories delimited when there are multiples? For instance, if it is a space, can we assume there are no sub-categories that have more than one word in them? Also not clear is how hashtag tags relate to categories, as the only containers your describe are for categories.

The questions aren’t simple pedantry, but rather just checking you have clear rules upon which your action code can act.

** A workaround is possible using aliases created by agents, which are then moved out of the agent. However, as the now-missing alias is recreated next time the agent runs (i.e. quickly!) you also need to ensure you create/move only as many aliases as required before altering the source note so it no longer matches the query. This can be done but should be thought of as a one-pass or occasional process as a bit of care is needed to avoid spamming the document with surplus aliases—which is, at present, why you can’t use action code directly to generate an alias.

Thanks very much for your reply! Yes, you’re quite right: I forgot to mention that delineation. Let me preface my answer by saying that I would be more than happy to change the syntax of how I title my subcategory names to ensure this process works smoothly. Right now, for a single subcategory I’ve just included a single subcategory. But for more than one, I preface each subcategory with a single hyphen:

Apples

v.

-Apples
-Peaches
-Plums

Again, I’m totally happy to change the way I delineate multiple subcategories. I’m also happy to pursue another way of replicating notes (i.e., through aliases) to different containers, if you feel there’s better / easier way to do so. I’ll follow your lead, and welcome your suggestions.

Thank you.

So you have a subcategory note whose title might be “-Apples -Peaches -Plums” and this note needs to sit under the “Apples” category and also have an alias under the “Peaches” and “Plums” categories? Does the title change once the aliases are created?

Be aware that aliases can’t have children, given that you appear to have a multi-level category set. If this were my data, I’d start by taking a small section of theMarginNote data and manually building out how it make look. This will help make plain the transforms necessary, whether you currently have the right metadata to enable that. HTH.

Yes.

I’m not sure I follow this question. When I create titles with multiple subcategories, I don’t expect them to change. I suppose they could – it doesn’t really matter to me – my main concern is that the note is replicated in appropriate containers. That’s all.

I think I follow your point. Here’s the deal… MarginNote isn’t just an app for annotations; part of what makes it such a unique and powerful tool is that it allows users to build out these annotations in a structure – both through outline and mind map formatting. So, I do all of that organizational work with my notes (discrete annotations) there, then export it to iThoughtsX, tinker with it a bit more (if need be), and then export it to an OPML format for Tinderbox.

So, in a sense I’ve already sorted out where I want things to go. The only missing peg of this process (insofar as I can tell!) is creating the replications / aliases for subcategories – or containers within Tinderbox. Of course I could certainly be overlooking something…

1 Like

I just realized that I failed to fully answer this question – or clarify it, adequately. I’m indifferent to the oder in which these aliases are created, do it doesn’t matter to me which one goes first, second, and so forth. Just as long as they replicate! Thanks.

Thanks for all that, detail helps (not least as I’d never heard of MarginNote before).

One thing that will help you in the transfer process are prototypes. These enable you to apply a consistent formatting/styling whilst also letting you easily query, and act on, an otherwise disparate group of notes.

Thus I’d make a prototype for Sub-Categories, in part to make sure we only act on the notes we intend when working at scale with agents. This allows us to get from:

To - and what I understand is the desired outcome:

I’ll explain the process in the next post…

First we make a prototype “pSubCategories”.

ProTip: give prototypes a $Name you won’t use in a normal note - using a prefix character is a simple way. Some use an underscore or asterisk, I generally use a ‘p’ prefix. Whatever, it makes it less likely a normal note will need the same tile as a prototype.

I give the prototype the rule: $MyList=$Name.replace(" ",";");

I used $MyList only to indicate the data type needed you can use any List-type attribute. We need a List-type and not a set as we don’t want the list order to change.

Once $MyList is populated remove (or disable) the Rule. This is because we’re now going to process the sub-category notes based on that list and alter the list in the process.

Make an agent:
Query: $Prototype=="pSubCategory"

Check you get all the notes matching that you expect. If not fix that before adding an action to the agent:

$Container(original)=$MyList.at(0).substr(1);

This should move all original sub-category notes under the first-named category in the note name. Check that’s worked then replace the agent’s action with this:

if($Name(parent(original))==$MyList.at(0).substr(1)){$MyList=$MyList-$MyList.at(0);}

This cleans the $MyList values of single entry sub-categories as we don’t need to process them further.

Now delete the agent action and only then amend its query to:
$Prototype=="pSubCategory"&$MyList.count>0

This filters out the single category items we finished above. Now add the agent action:

$Container=$MyList.at(0).substr(1);
$MyList=$MyList-$MyList.at(0);

Check the data and delete the agent. You’ve got to the stage shown in the second image above. This, as I understand it is the completion of the process asked at outset.

Thank you very much for this. I’ve been reviewing and re-reading everything you wrote – all of which I greatly appreciate.

I’m relatively new to Tinderbox, so I’m trying to catch up with its organizational striation – as well as its configuration and syntax.

Before I proceed further with this, I just want to clarify that I do not need to include every combination of subcategories as part of what you’ve outlined, correct? Doesn’t seem to be the case based on what you’ve outlined, but I just want to be totally sure. Thanks!

Also, just so I’m totally clear, when you say: First we make a prototype “pSubCategories” – you mean that the prototype should read pApples or… $MyList=$pApples.replace(" “,”;"); Is that right? Or Query: $Prototype==“pApples” – correct?

I’ll proceed with this once I hear back from you. Thanks again!

I’m sorry, I don’t understand. I’ve merely implemented an example based on the sample info you gave. without seeing the wider dataset it’s hard to comment. I’d assume you know what categories and sub-categories you want to import

No. Like I say, the first task is to make a prototype to be used by the sub-category notes. I suggest the tilte ($Name) of the prototype be set as pSubCategories and that is what I used in the illustrations. What I inadvertently did omit** was an instruction that after the prototype has been created, you should then set all the subcategory notes to use that prototype. If you don’t yet know how do do that see the app’s Help, the “Getting started with Tinderbox” PDF in the Help menu or my aTbRef resource. there are a number of ways to do this - read up and choose the method you prefer.

** I’ll go back and amend the earlier post so later readers aren’t confused.

The rule I mention is applied to the prototype [sic] so that it is inherited by all the notes using that prototype. That is a key point of a prototype. It lets you set code in one place and have it run in many notes rather then having to set it directly in each note. By the same token you can remove the rule and all the inheriting notes reflect that change.

Does that help?

Thank you, Mark. Yes, all of that help. To address our exchange…

Thanks for your reply. Let me back up a sec… In process I described I am: (1) creating MarginNote annotations, titles for those annotations, and then organizing each of them within MarginNote (via outlines and mind maps); (2) exporting these notes, and their hierarchies, into iThoughtsX, and then (3) exporting them once more from iThoughtsX into an OPLM format, and therein opening them in Tinderbox. As a result of this process, I’m creating categories and subcategories for notes in Tinderbox. In other words, the import of notes – from MarginNote to Tinderbox – will, by virtue of the process I’ve described, come with an existing category and subcategory structure.

The only thing is that some of these notes have more than one subcategories. MarginNote doesn’t create aliases (or replicants), and so that’s the process I’m trying to set up in Tinderbox – that is, for notes that have more than one subcategory.

Forgive me if I’m being redundant, but I just wanted to clarify that. And I want to ensure that I can still follow what you’ve outlined here.

BTW, I’m following the 2015 version of “Getting Started with Tinderbox.” Is that the one you’re suggest I use as I try to follow your directions? And what would you suggest and the preferred method for setting up prototypes?

Thank you again. Truly.

The PDF in the current Tinderbox is marked as 2015-7 on page 1 and at the bottom of page 2 is noted as being written as at v6.1.0; the getting started phase isn’t affected by changes since that version.

Re setting up prototypes and inheritance, also see my articles here, here and here: written for v6 they still hold true.

Tip: if adding your own prototypes for the first time, first add a built-in prototype (see File menu) to you doc. Doesn’t matter which one but it will set up a ‘Prototypes’ container for you which in turn makes any new child note added to it into a prototype (and ensures they’re all in one place). How you title prototypes is down to personal taste but I’d suggest names that will always be unique but consistent in identifying the note a prototype just by name alone.

This is more ambiguous than imagined as you don’t say if categories and/or sub-categories nest within one another. Nesting category notes is not problematic but nested sub-categories are as a sub-category that has a nested sub-category can’t be aliased. Or rather it can but the alias can’t show its original note’s children/descendants.

At this stage it would be much easier if you where able to a show an example of the sort of structure your OPML creates so we can see the actual default structure and better assess what can can’t be done.

A good tip when starting a project is to take a representative set of your source data and import it (by any of the supported methods) see what turns up and what metadata or data structure has not transferred.

Hi Mark,
I was thinking exactly the same thing. I’m attaching an image of what I’ve created from my MarginNote (annotated)->iThoughtsX (converted)->Tinderbox (processed) workflow.

You’ll see that through this process I’ve created categories and subcategories with notes. The notes with more than one subcategory are the ones which I want to make into alias so that they can be replicated in more than one category. Does this make sense?

By the way, I’m happy to pursue a different approach to this as well within Tinderbox – seriously glad to take on another way that would be easier, most efficient and a better organizational approach.

Also, and we can get into this later, within the note itself there are occasionally hashtags for things like #timeline. I want to first figure out how to set up the aliases, but then figure out how to employ a similar system of prototypes and agents to group together similar hashtags. Make sense?

Thanks so much again!

Whilst respecting your wanting to replicate how an older app works, seeing the screengrab does gives pause for thought. It seems to me the real notes are all at the second level but with without real titles and that the existing titles represent one or two (if you want sub-categories).

As an experiment (as I don’t have the TBX shown):

  • Add a prototype and apply it to all level 2 (i.e. child) notes.
  • Set the prototype’s Key Attributes (KA) to show $URL and $Tags.
  • Set the prototype’s $RuleEnabled to false (see the ‘enabled’ tick-box on the Rile Inspector).
  • Make the prototype’s Rule: $Tags=$Tags+$Name(parent)+$Name.replace("-","").replace("\n",";");
  • Add a new tab and set the type to Attribute Browser (right-click the tab title to do this). Set the attribute to group 'References and attribute ‘Tags’.

You’ll see something like this:

Notice how notes now list under all the categories (using $Tags data) for which it has a value. If you move the existing sub-categories to a new container to hold just the current sub-category notes (as I notice category containers have no text/content) and set that as the Attribute Browser’s scope then the area marked ‘ignore’ in my screen gab won’t appear.

Then, give your notes more presentative values as to their content and I think you’ve far more usable data - and without losing the $URL links to the MarginNote sources.

I’d welcome the views of other users here as this is beginning to feel like a monologue! Anyway, the takeaway is Tinderbox allows you to break out of the limitations of only-outlie-based data .

Hi Mark,
Thank you again. Al of this is great!

I’m going to upload two other screenshot examples, and then them send you via the address you sent. They just offered different ways in which I can set up notes from MarginNote, and one of these examples could provide a better way to process aliases (and other things) in Tinderbox. I have a few ideas around the same schema; nothing too complicated – just slightly different variations on the same basic theme. Will send this to you soon.
Thank you so much again…

Ok, I’m attaching two new images reflecting two new approaches of what I’ve created from my MarginNote (annotated)->iThoughtsX (converted)->Tinderbox (processed) workflow.

I actually think these new approaches will work better both for on the MarginNote end, and will better empower Tinderbox to do what it does best via prototypes and agents, etc.

(Quickly…yes, it’s true I’m currently using Tinderbox 6, but I actually just bought the upgrade and am awaiting for it to arrive.)

A quick preface about MarginNote annotations before I explain the reasoning behind my original approach, and two additional approaches that I’m including in this post. In short, MarginNote provides tools to highlight, create and affix hashtags, and provide notes in the form of titles and / or comments to individual annotations.

In a sense, the multiple titles names – signifying multiple subcategories – are a kind of workaround solution for creating hierarchal tags or hashtags. As great as MarginNote is, it doesn’t have a great hashtag system; it’s a bit clunky that way and hasn’t yet set up a tidy organizational system of hashtags tailored for specific topics (e.g., #endometriosis or #balzak), though that might change. And so, I rely on using hashtags for generic research-related work (e.g., #questions, #research, #timeline, etc.).

As I’ve explained before, MarginNote users can create parent categories (what they call “parent nodes” – there also sibling, child, and free nodes), and then users can move individual annotations to categories / nodes, accordingly, within the app’s outline or mindmap modes.

After I’ve moved everything around, I export a file iThoughtsX where I convert it to OPMP, and then open it in Tinderbox. As a result of this process, the MarginNote nodes and annotations eventually become Tinderbox containers and notes, respectively. (By the way, the highlight color that I use in MarginNote shows up iThoughtsX, but vanishes in Tinderbox.)

Anyway, I originally put the subcategories in the title section of MarginNote’s annotations, just because it’s easier to identify them and move them to their respective categories. But, as you rightly pointed out, they are [quote=“mwra, post:15, topic:901”]
without real titles and that the existing titles represent one or two (if you want sub-categories).
[/quote]

Also, it seems that my original process of shaping a structure in MarginNote and using Tindbox to create aliases is both too laborious in MarginNote and underutilizes Tindbox’s power.
Preamble over!

Ok, I’m attaching new approaches A & B, which are very similar with one important difference. In both cases, unlike the previous one I uploaded, I separate the categories (nodes) from the subcategories (notes); there’s no more parent-child relationship there, though as you’ll see I’ve created parent-child relationships with catalogue containers. (I also created the same structure for the hashtags and research questions.) As I understand one of your earlier posts, it seems that doing this will better allow Tinderbox’s prototypes and agents to automatically group notes with their subcategories in their respective category - containers. The only different is…

For Example A, I’ve kept the subcategories names in the MarginNote and Tinderbox titles.

For Example B, I (1) moved the subcategories names from the MarginNote titles to the comments, which thereby moves them into Tinderbox’s text panel; (2) I’ve wrapped the subcategories names with quotes – just to provide them with clearer definition for Tinderbox’s agents / prototypes process (happy to use another kind of syntax if there’s a better way), and; (3) I’ve filled the MarginNote and Tinderbox titles with keywords that relate to each annotations, which seems like a more appropriate way to use titles!

Like I said, I think I’ve made improvements to the work approaches that should make the Tinderbox process work much better. Please let me know what you think whenever possible and we’ll proceed from here.

Thank you so much, Mark (et. al.). Cannot express my full gratitude… And I’m sorry for the length of this post! Just thought it would be easier to spell this out clearly once. Thank!

For me ‘B’ makes more sense. Assumptions:

  • this import is a once-off process and then occasionally repeated for new notes
  • there is no expectation of a merge (i.e. to import/update existing TB items) - as Tinderbox doesn’t have such.

Example B makes it easier to break away from the limitations of the tagging in MarginNote (MN). That’s not to disparage the latter but looking at the utility but it’s more about the note generation than classification. It’s better to bring in the tags an re-sort them here. Whilst some systems such as Linnaean species have a natural classification, many keyword/tag systems try and add hierarchy to make it easier to find existing tags. But it’s not necessarily a need or a virtue.

I’d suggest importing all your MN tags as at present and then using action code to move them (minus the #) to $Tags and delete them from $Text where they just add noise. Instead use Key Attributes (KA - better done using prototypes) to show $Tags as a KA. Once in $Tags you can use actions like `values(“Tags”)" to get a unique list of the values so you can weed/improve them or possibly split/move some values to separate Set-type attribute so you’ve multiple discrete sets of metadata (again easily seen/maintained as KA); tip - using a Set instead of a List ensure individual note’ hold any given value once within it’s list.

If used to only having the option of one tag/keyword list you might be conditioned to that. But, for example let’s assume you’ve ‘tags’ that include names of key people in the topic and key timeline events. These might be better split off as $Events and $People (the names are just examples). This separation make it easier to display and investigate nuances in you ‘tags’ that are harder to do when all mixed together.

For now, I’d concentrate on importing the MN tags and once in Tinderbox you can figure what if any further triage is needed.

For the (?terminology) items you’ve put in quotes, I assume these are going into another Set-type attribute, but not $Tags. I’d not recommend using quotes as a mark-up as quotes are used as (text) ‘string’ delimiters in Tinderbox action code so now you’ve lots of gnarly quote escaping to do. I’d use a different easy prefix like ‘@’, assuming your notes don’t contain email addresses. If so choose another delimiter but note slashes, quotes or brackets/braces of any type.

As a further point, I’d make you # and @ values into discrete paragraphs. In other words, no hard line breaks between first # tag and last # tag but a line return after the latter, same for the ‘@’ (or whatever marker) tags. Within these paragraphs, use a comma between terms (thus spaces become part of terms as opposed to part of their separators. So this sort of thing:

#thing,#other thing,#stuff
@something,@different,@more stuff,@anything

Thus makes it easier to fine and remove the paragraph starting with #, removing the # prefixes, parsing the terms to a list and putting that in a Set-type attribute.

We can go into the exact how’ of the latter in due course, but I think that’s the approach I’d recommend.