Unlink broken for named links?

Hi, unlinkTo and unlinkFrom don’t appear to work for named links.

Test by linking one note to another with a named link, then create a stamp with:

$HoverExpression=links.outbound..$Path;
unlinkTo(links.outbound..$Path)

and apply it to the source note. It fails to unlink existing outbound links (you can easily verify the path exists by hovering over the item). Works for *untitled links. Passing in the link type to unlink still fails.

I’d agree something is amiss. Calling unlinkTo() on an item or list with no link type argument should delete all links according to my documentation, which makes me wonder if the latter is wrong or functionality has changed.

On reflection, there ought to be a way to unlink (or link) only un-typed notes. If so, (un);linking all links, typed and untyped probably needs a special filter. '*" seems to do the trick. There is a separate added issue re your use of links() as it needs to be evaluated before use - which some extra parentheses fix. Thus:

unlinkTo((links.outbound..$Path),"*")

Testing in v7.3.1, this works for me in removing all outbound links (typed and untyped) from a note.

Here also.

This is getting rid of both basic and text links. I wonder if an additional optional parameter is needed to limit the scope of unlinkTo() and unlinkFrom() to basic or text (or both if the parameter is not provided).

I’ve reported this issue on the backstage, as despite my guess, I see app Help does state

If linkType is not supplied, unlink actions will remove links of all link types.

…although clearly this is not the case. Fortunately, we have a workaround pro tem.

As to basic vs text links, at present the process does both. Perhaps make a feature request that unlinking operators have an optional third parameter with values ‘basic’, ‘text’ or blank. If the latter the current behaviour of deleting both basic and text links will apply.

For my own part I generally use these functions only for basic linking (and for notes generally lacking $Text, or text links) and I’d overlooked unintentional blow-back by unlinking removing text links. This also shows a disparity in scope of action between link which only ever creates basic links and unlink which potentially removes all links - both basic and text.

The extra brackets on the path did the trick. Looks like it’s just the docs that need updating.

Seems:

unlink(path) will unlink basic or unnamed links only

unlink(path, 'exp') will unlink links whose text matches expression exp

so unlink(path, 'agree|disagree') will remove agree and disagree links, unlink(path, '.') will remove everything.

Of course unlink(path, 'agree') will remove both agree and disagree links as it matches against both :confused:, but unlink(path, '^agree$') will work in that case.

Yes, the latter is as documented - input parameter #2 is a regex pattern. However, your last reminds me of a potential gotcha for the less-tech user trying to use this who might not understand such accidental pattern matching.

Those two are different things. Basic links are note-to-note links, whereas text link are from an anchor in $Text to another note. Both forms of link can optionally have a link type.

I may have misunderstood your opening question, but it is the case that unlinkTo(path) doesn’t unlink basic/text links with link types although the documentation says it should. I have already reported this, off-forum.

I got tripped up with my use of links, and the built in documentation for unlinkXXX:

The first argument to each of these actions, is the name or path of a note, or a list of paths. The optional second argument is the link’s type; if no argument is supplied, untitled links are used. Unlike links(), above, the linkType argument is not a regex and is a string literal.

The description in atbref7 is mentions it’s a regex but then states

all link types: unlinkTo(“Some note”)
only link type ‘agree’: unlinkTo(“Some note”,“agree”)

which is not quite right either.

Just tested the unlinking, and without the second argument it will unlink *untitled links (basic) and text [[xxx]] links. You can change the text link to a name one after it’s created in which case it doesn’t get removed.

I’d agree. The point avoid unintended regex pattern collision (i.e. ‘agree’ matching ‘disagree’) is on my to do list. the other points need engineering works so can’t be fixed at user level.

This sort of progress will be familiar to long-term users. The app is a big toolbox and a feature added for one tasks often then allows other uses which show unexpected edge cases (as they weren’t part of the original design concept). AFAIR, the link/unlink was designed for doing work on basic links and where text links weren’t part of the picture. I guess that will need to change!

What would be really nice is being able to programmatically manipulate text links. From what I can see there is no current way to do this within Tinderbox.

I can see how to do it outside but it’s a bit rude and would lead to race conditions etc - parse and modify the xml, text links are separate entities that have the note id and the start and end positions of the text to be rendered as a link, so it would be easy enough to manipulate them programatically in any language with xml and string routines.

An even better approach would be to provide a complete API/bridge to a language like python. It’s always hard to roll your own scripting and get it consistent and expressive. (If parsing the file format in another language starts to look appealing, the internal scripting has failed.)