From 7b955ef26a539c9c6155f4c8e38a172703bcaba3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20S=2E=20=C5=81ukasiewicz?= Date: Fri, 11 Oct 2024 15:39:14 +0200 Subject: [PATCH] Index wikilinks in frontmatter strings (#1000) (#1066) --- plugs/index/page_links.ts | 37 +++++++++++++++++++++++++++++++++++++ website/YAML.md | 24 +++++++++++++++++++++++- 2 files changed, 60 insertions(+), 1 deletion(-) diff --git a/plugs/index/page_links.ts b/plugs/index/page_links.ts index bba0f6f4f..1d177bf6b 100644 --- a/plugs/index/page_links.ts +++ b/plugs/index/page_links.ts @@ -1,4 +1,5 @@ import { + collectNodesOfType, findNodeOfType, renderToText, traverseTree, @@ -206,6 +207,42 @@ export async function indexLinks({ name, tree }: IndexTreeEvent) { } } } + + // Also index links used inside quoted frontmatter strings like "[[Page]]" + // must match the full string node, only allowing for quotes and whitespace around it + if (n.type === "FrontMatter") { + // The YAML in frontmatter is parsed by CodeMirror itself + for (const textNode of collectNodesOfType(n, "string")) { + const text = textNode.children![0].text!; + const trimmed = text.replace(/^["'\s]*/, "").replace(/["'\s]*$/, ""); + // Make sure we search from the beginning, when reusing a Regex object with global flag + wikiLinkRegex.lastIndex = 0; + const match = wikiLinkRegex.exec(text); + // Search in entire node text to get correct position, but check for full match against trimmed + if (match && match[0] === trimmed) { + const [_fullMatch, firstMark, url, alias, _lastMark] = match; + const pos = textNode.from! + match.index! + firstMark.length; + const link: any = { + ref: `${name}@${pos}`, + tag: "link", + page: name, + snippet: extractSnippetAroundIndex(pageText, pos), + pos: pos, + asTemplate: false, + }; + if (looksLikePathWithExtension(url)) { + link.toFile = resolvePath(name, url); + } else { + link.toPage = resolvePath(name, parsePageRef(url).page); + } + if (alias) { + link.alias = alias; + } + updateITags(link, frontmatter); + links.push(link); + } + } + } return false; }); diff --git a/website/YAML.md b/website/YAML.md index 12f575c71..88ddedbc7 100644 --- a/website/YAML.md +++ b/website/YAML.md @@ -1,3 +1,25 @@ YAML stands for “YAML Ain’t Markup Language.” More information can be found at [the YAML website](https://yaml.org/). -SilverBullet uses YAML in various contexts, specifically [[Frontmatter]]. \ No newline at end of file +SilverBullet uses YAML in various contexts, specifically [[Frontmatter]] and [[Space Config]] + +# Internal links +Many string values can be written directly in YAML without any quoting, like: +```yaml +property: value +``` + +However when you want to reference [[Links|a page]] or [[Command links|command]] you will need to quote the full link: +```yaml +some page: "[[Pages]]" +list of pages: + - "[[Pages]]" + - "[[Links]]" +``` + +This is because the square brackets used in the internal link format have a meaning in YAML as well. So an unquoted link is parsed as list inside a list: +```yaml +some page: [[Pages]] +equivalent yaml: [ + [ "Pages" ] +] +```