obsidian-frontmatter-links icon indicating copy to clipboard operation
obsidian-frontmatter-links copied to clipboard

Multiple links in the same string are not properly handled

Open imevul opened this issue 1 year ago • 1 comments

With frontmatter like this:

someList:
  - Some text "[[And a link]]" more text "[[Another link|with alias]]"

The parsing of links gets messed up and gets treated like one big, weird link. This can be partially fixed by changing the regex to exclude opening brackets (and the pipe): /\[\[([^\[\|]+)\|([^\[]+)\]\]/m, but that does not completely solve the problem.

Even with the updated regex addFrontmatterLinksToCache() function only catches the last link. Needs to be rewritten using .matchAll and the /g flag.

findLinks() and styleLinks() could probably benefit from the same .matchAll and regex updates. Adding quotes around the entire list item (correct YAML syntax) is even more broken: "Some text [[And a link]] more text [[Another link|with alias]]"

I think that's because of them being a part of the same slice, so the entire quoted string gets linked (node.from -> node.to) instead of the individual links inside the slice.

The expected behaviour is that the individual links are properly styled and added to the graph.

If I get anywhere, I'll send a PR, but it will probably require a rewrite of all the regex parts.

imevul avatar Jun 08 '23 11:06 imevul

This is trickier than I thought. Mostly gotten multi-link parsing to work in findLinks() using the following code (no guarantee that it's stable):

            const pattern = /\[\[?([^\[\|]+?)(?:(?:\||\]\(())([^\[\(]+?))?(?:\]\]|\))/gm;
            let start = node.from + 1;
            let from;
            let to;
            let matches = [...text.matchAll(pattern)];
            matches.forEach((match) => {
              href = match[1];
              alias = match[3];
              from = start + match.index;
              to = from + match[0].length;
              
              if (match[2] === '') { // Use presence of empty capture group to detect markdown links
                markdownLink = true;
              }
              
              linkSlices.push({
                originalText: match[0],
                href,
                alias,
                from: from,
                to: to,// - (settings.hideQuotes ? 0 : 1),
                markdownLink
              });
            });

But I'm not really sure what to do about the hideQuotes setting in that case, since the entire string is no longer replaced. Probably gotta detect that as well (from == start && to == node.to or something). This also doesn't handle the import_valid_url2 case, which I don't even know what it does. And still need to do something about the cache.

imevul avatar Jun 08 '23 17:06 imevul