Trikzon / obsidian-frontmatter-links

An Obsidian plugin that renders links in a note's frontmatter as links.
MIT License
64 stars 8 forks source link

Multiple links in the same string are not properly handled #29

Open imevul opened 1 year ago

imevul commented 1 year ago

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 commented 1 year ago

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.