@quartz-community/bases-page 1.0.1 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,22 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.1.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 6ee2eda: `file.name` includes the file's extension, as in Obsidian: `Note.md`, `Plan.canvas`. Use `file.basename` for the name without it. Filters, formulas and sorting that compare `file.name` (`file.name == "Plan.canvas"`, `file.name.endsWith(".canvas")`) now give the same results as in Obsidian. **Changed:** a filter written for the old value, such as `file.name == "Note"`, needs `file.basename` instead. Tables still show the name without the extension as the link to each file.
8
+
9
+ ### Patch Changes
10
+
11
+ - 3e6b70b: Resolve wikilink-valued strings (`[[note]]`, `[[note|alias]]`, `[[note#heading]]`) the way Obsidian does, so link-valued frontmatter such as `location: "[[note]]"` works in `asFile()`, `link()` and `list.contains(this)`. Like Obsidian, `link()` keeps a wikilink's `#heading` but not its alias, so the link text is the note's name.
12
+ - 9cda99f: Fix `this` in bases embedded in notes and stop listing Quartz's generated pages as notes:
13
+
14
+ - `this.file` is now the full file of the note the base is embedded in, so `this.file.asLink()` works. Filters such as `file.links.contains(this.file.asLink())` and `authors.contains(this.file.asLink())` match the notes that link to the embedding note, and a link property matches whether it holds one link or a list of links. `contains()` with a missing value no longer matches every note.
15
+ - `file.inFolder(this.file.folder)` in a note at the content root now matches every note, as in Obsidian. `inFolder("")` and `inFolder("/")` both mean the root.
16
+ - Pages that Quartz generates, such as the 404 page, tag pages, the tags index and folder listings, no longer appear as notes in base views.
17
+
18
+ - 584d465: Bundles `@quartz-community/utils` 1.1.0: a short wikilink to an Obsidian folder note (`[[Topic]]` for `Topic/Topic.md`) reaches the folder page, and anchors to headings use the same slug as heading ids. `github-slugger` is no longer a dependency of this plugin.
19
+
3
20
  ## 1.0.1
4
21
 
5
22
  ### Patch Changes
@@ -634,14 +634,6 @@ function parse(tokens) {
634
634
  return expression;
635
635
  }
636
636
 
637
- // node_modules/github-slugger/regex.js
638
- var regex = /[\0-\x1F!-,\.\/:-@\[-\^`\{-\xA9\xAB-\xB4\xB6-\xB9\xBB-\xBF\xD7\xF7\u02C2-\u02C5\u02D2-\u02DF\u02E5-\u02EB\u02ED\u02EF-\u02FF\u0375\u0378\u0379\u037E\u0380-\u0385\u0387\u038B\u038D\u03A2\u03F6\u0482\u0530\u0557\u0558\u055A-\u055F\u0589-\u0590\u05BE\u05C0\u05C3\u05C6\u05C8-\u05CF\u05EB-\u05EE\u05F3-\u060F\u061B-\u061F\u066A-\u066D\u06D4\u06DD\u06DE\u06E9\u06FD\u06FE\u0700-\u070F\u074B\u074C\u07B2-\u07BF\u07F6-\u07F9\u07FB\u07FC\u07FE\u07FF\u082E-\u083F\u085C-\u085F\u086B-\u089F\u08B5\u08C8-\u08D2\u08E2\u0964\u0965\u0970\u0984\u098D\u098E\u0991\u0992\u09A9\u09B1\u09B3-\u09B5\u09BA\u09BB\u09C5\u09C6\u09C9\u09CA\u09CF-\u09D6\u09D8-\u09DB\u09DE\u09E4\u09E5\u09F2-\u09FB\u09FD\u09FF\u0A00\u0A04\u0A0B-\u0A0E\u0A11\u0A12\u0A29\u0A31\u0A34\u0A37\u0A3A\u0A3B\u0A3D\u0A43-\u0A46\u0A49\u0A4A\u0A4E-\u0A50\u0A52-\u0A58\u0A5D\u0A5F-\u0A65\u0A76-\u0A80\u0A84\u0A8E\u0A92\u0AA9\u0AB1\u0AB4\u0ABA\u0ABB\u0AC6\u0ACA\u0ACE\u0ACF\u0AD1-\u0ADF\u0AE4\u0AE5\u0AF0-\u0AF8\u0B00\u0B04\u0B0D\u0B0E\u0B11\u0B12\u0B29\u0B31\u0B34\u0B3A\u0B3B\u0B45\u0B46\u0B49\u0B4A\u0B4E-\u0B54\u0B58-\u0B5B\u0B5E\u0B64\u0B65\u0B70\u0B72-\u0B81\u0B84\u0B8B-\u0B8D\u0B91\u0B96-\u0B98\u0B9B\u0B9D\u0BA0-\u0BA2\u0BA5-\u0BA7\u0BAB-\u0BAD\u0BBA-\u0BBD\u0BC3-\u0BC5\u0BC9\u0BCE\u0BCF\u0BD1-\u0BD6\u0BD8-\u0BE5\u0BF0-\u0BFF\u0C0D\u0C11\u0C29\u0C3A-\u0C3C\u0C45\u0C49\u0C4E-\u0C54\u0C57\u0C5B-\u0C5F\u0C64\u0C65\u0C70-\u0C7F\u0C84\u0C8D\u0C91\u0CA9\u0CB4\u0CBA\u0CBB\u0CC5\u0CC9\u0CCE-\u0CD4\u0CD7-\u0CDD\u0CDF\u0CE4\u0CE5\u0CF0\u0CF3-\u0CFF\u0D0D\u0D11\u0D45\u0D49\u0D4F-\u0D53\u0D58-\u0D5E\u0D64\u0D65\u0D70-\u0D79\u0D80\u0D84\u0D97-\u0D99\u0DB2\u0DBC\u0DBE\u0DBF\u0DC7-\u0DC9\u0DCB-\u0DCE\u0DD5\u0DD7\u0DE0-\u0DE5\u0DF0\u0DF1\u0DF4-\u0E00\u0E3B-\u0E3F\u0E4F\u0E5A-\u0E80\u0E83\u0E85\u0E8B\u0EA4\u0EA6\u0EBE\u0EBF\u0EC5\u0EC7\u0ECE\u0ECF\u0EDA\u0EDB\u0EE0-\u0EFF\u0F01-\u0F17\u0F1A-\u0F1F\u0F2A-\u0F34\u0F36\u0F38\u0F3A-\u0F3D\u0F48\u0F6D-\u0F70\u0F85\u0F98\u0FBD-\u0FC5\u0FC7-\u0FFF\u104A-\u104F\u109E\u109F\u10C6\u10C8-\u10CC\u10CE\u10CF\u10FB\u1249\u124E\u124F\u1257\u1259\u125E\u125F\u1289\u128E\u128F\u12B1\u12B6\u12B7\u12BF\u12C1\u12C6\u12C7\u12D7\u1311\u1316\u1317\u135B\u135C\u1360-\u137F\u1390-\u139F\u13F6\u13F7\u13FE-\u1400\u166D\u166E\u1680\u169B-\u169F\u16EB-\u16ED\u16F9-\u16FF\u170D\u1715-\u171F\u1735-\u173F\u1754-\u175F\u176D\u1771\u1774-\u177F\u17D4-\u17D6\u17D8-\u17DB\u17DE\u17DF\u17EA-\u180A\u180E\u180F\u181A-\u181F\u1879-\u187F\u18AB-\u18AF\u18F6-\u18FF\u191F\u192C-\u192F\u193C-\u1945\u196E\u196F\u1975-\u197F\u19AC-\u19AF\u19CA-\u19CF\u19DA-\u19FF\u1A1C-\u1A1F\u1A5F\u1A7D\u1A7E\u1A8A-\u1A8F\u1A9A-\u1AA6\u1AA8-\u1AAF\u1AC1-\u1AFF\u1B4C-\u1B4F\u1B5A-\u1B6A\u1B74-\u1B7F\u1BF4-\u1BFF\u1C38-\u1C3F\u1C4A-\u1C4C\u1C7E\u1C7F\u1C89-\u1C8F\u1CBB\u1CBC\u1CC0-\u1CCF\u1CD3\u1CFB-\u1CFF\u1DFA\u1F16\u1F17\u1F1E\u1F1F\u1F46\u1F47\u1F4E\u1F4F\u1F58\u1F5A\u1F5C\u1F5E\u1F7E\u1F7F\u1FB5\u1FBD\u1FBF-\u1FC1\u1FC5\u1FCD-\u1FCF\u1FD4\u1FD5\u1FDC-\u1FDF\u1FED-\u1FF1\u1FF5\u1FFD-\u203E\u2041-\u2053\u2055-\u2070\u2072-\u207E\u2080-\u208F\u209D-\u20CF\u20F1-\u2101\u2103-\u2106\u2108\u2109\u2114\u2116-\u2118\u211E-\u2123\u2125\u2127\u2129\u212E\u213A\u213B\u2140-\u2144\u214A-\u214D\u214F-\u215F\u2189-\u24B5\u24EA-\u2BFF\u2C2F\u2C5F\u2CE5-\u2CEA\u2CF4-\u2CFF\u2D26\u2D28-\u2D2C\u2D2E\u2D2F\u2D68-\u2D6E\u2D70-\u2D7E\u2D97-\u2D9F\u2DA7\u2DAF\u2DB7\u2DBF\u2DC7\u2DCF\u2DD7\u2DDF\u2E00-\u2E2E\u2E30-\u3004\u3008-\u3020\u3030\u3036\u3037\u303D-\u3040\u3097\u3098\u309B\u309C\u30A0\u30FB\u3100-\u3104\u3130\u318F-\u319F\u31C0-\u31EF\u3200-\u33FF\u4DC0-\u4DFF\u9FFD-\u9FFF\uA48D-\uA4CF\uA4FE\uA4FF\uA60D-\uA60F\uA62C-\uA63F\uA673\uA67E\uA6F2-\uA716\uA720\uA721\uA789\uA78A\uA7C0\uA7C1\uA7CB-\uA7F4\uA828-\uA82B\uA82D-\uA83F\uA874-\uA87F\uA8C6-\uA8CF\uA8DA-\uA8DF\uA8F8-\uA8FA\uA8FC\uA92E\uA92F\uA954-\uA95F\uA97D-\uA97F\uA9C1-\uA9CE\uA9DA-\uA9DF\uA9FF\uAA37-\uAA3F\uAA4E\uAA4F\uAA5A-\uAA5F\uAA77-\uAA79\uAAC3-\uAADA\uAADE\uAADF\uAAF0\uAAF1\uAAF7-\uAB00\uAB07\uAB08\uAB0F\uAB10\uAB17-\uAB1F\uAB27\uAB2F\uAB5B\uAB6A-\uAB6F\uABEB\uABEE\uABEF\uABFA-\uABFF\uD7A4-\uD7AF\uD7C7-\uD7CA\uD7FC-\uD7FF\uE000-\uF8FF\uFA6E\uFA6F\uFADA-\uFAFF\uFB07-\uFB12\uFB18-\uFB1C\uFB29\uFB37\uFB3D\uFB3F\uFB42\uFB45\uFBB2-\uFBD2\uFD3E-\uFD4F\uFD90\uFD91\uFDC8-\uFDEF\uFDFC-\uFDFF\uFE10-\uFE1F\uFE30-\uFE32\uFE35-\uFE4C\uFE50-\uFE6F\uFE75\uFEFD-\uFF0F\uFF1A-\uFF20\uFF3B-\uFF3E\uFF40\uFF5B-\uFF65\uFFBF-\uFFC1\uFFC8\uFFC9\uFFD0\uFFD1\uFFD8\uFFD9\uFFDD-\uFFFF]|\uD800[\uDC0C\uDC27\uDC3B\uDC3E\uDC4E\uDC4F\uDC5E-\uDC7F\uDCFB-\uDD3F\uDD75-\uDDFC\uDDFE-\uDE7F\uDE9D-\uDE9F\uDED1-\uDEDF\uDEE1-\uDEFF\uDF20-\uDF2C\uDF4B-\uDF4F\uDF7B-\uDF7F\uDF9E\uDF9F\uDFC4-\uDFC7\uDFD0\uDFD6-\uDFFF]|\uD801[\uDC9E\uDC9F\uDCAA-\uDCAF\uDCD4-\uDCD7\uDCFC-\uDCFF\uDD28-\uDD2F\uDD64-\uDDFF\uDF37-\uDF3F\uDF56-\uDF5F\uDF68-\uDFFF]|\uD802[\uDC06\uDC07\uDC09\uDC36\uDC39-\uDC3B\uDC3D\uDC3E\uDC56-\uDC5F\uDC77-\uDC7F\uDC9F-\uDCDF\uDCF3\uDCF6-\uDCFF\uDD16-\uDD1F\uDD3A-\uDD7F\uDDB8-\uDDBD\uDDC0-\uDDFF\uDE04\uDE07-\uDE0B\uDE14\uDE18\uDE36\uDE37\uDE3B-\uDE3E\uDE40-\uDE5F\uDE7D-\uDE7F\uDE9D-\uDEBF\uDEC8\uDEE7-\uDEFF\uDF36-\uDF3F\uDF56-\uDF5F\uDF73-\uDF7F\uDF92-\uDFFF]|\uD803[\uDC49-\uDC7F\uDCB3-\uDCBF\uDCF3-\uDCFF\uDD28-\uDD2F\uDD3A-\uDE7F\uDEAA\uDEAD-\uDEAF\uDEB2-\uDEFF\uDF1D-\uDF26\uDF28-\uDF2F\uDF51-\uDFAF\uDFC5-\uDFDF\uDFF7-\uDFFF]|\uD804[\uDC47-\uDC65\uDC70-\uDC7E\uDCBB-\uDCCF\uDCE9-\uDCEF\uDCFA-\uDCFF\uDD35\uDD40-\uDD43\uDD48-\uDD4F\uDD74\uDD75\uDD77-\uDD7F\uDDC5-\uDDC8\uDDCD\uDDDB\uDDDD-\uDDFF\uDE12\uDE38-\uDE3D\uDE3F-\uDE7F\uDE87\uDE89\uDE8E\uDE9E\uDEA9-\uDEAF\uDEEB-\uDEEF\uDEFA-\uDEFF\uDF04\uDF0D\uDF0E\uDF11\uDF12\uDF29\uDF31\uDF34\uDF3A\uDF45\uDF46\uDF49\uDF4A\uDF4E\uDF4F\uDF51-\uDF56\uDF58-\uDF5C\uDF64\uDF65\uDF6D-\uDF6F\uDF75-\uDFFF]|\uD805[\uDC4B-\uDC4F\uDC5A-\uDC5D\uDC62-\uDC7F\uDCC6\uDCC8-\uDCCF\uDCDA-\uDD7F\uDDB6\uDDB7\uDDC1-\uDDD7\uDDDE-\uDDFF\uDE41-\uDE43\uDE45-\uDE4F\uDE5A-\uDE7F\uDEB9-\uDEBF\uDECA-\uDEFF\uDF1B\uDF1C\uDF2C-\uDF2F\uDF3A-\uDFFF]|\uD806[\uDC3B-\uDC9F\uDCEA-\uDCFE\uDD07\uDD08\uDD0A\uDD0B\uDD14\uDD17\uDD36\uDD39\uDD3A\uDD44-\uDD4F\uDD5A-\uDD9F\uDDA8\uDDA9\uDDD8\uDDD9\uDDE2\uDDE5-\uDDFF\uDE3F-\uDE46\uDE48-\uDE4F\uDE9A-\uDE9C\uDE9E-\uDEBF\uDEF9-\uDFFF]|\uD807[\uDC09\uDC37\uDC41-\uDC4F\uDC5A-\uDC71\uDC90\uDC91\uDCA8\uDCB7-\uDCFF\uDD07\uDD0A\uDD37-\uDD39\uDD3B\uDD3E\uDD48-\uDD4F\uDD5A-\uDD5F\uDD66\uDD69\uDD8F\uDD92\uDD99-\uDD9F\uDDAA-\uDEDF\uDEF7-\uDFAF\uDFB1-\uDFFF]|\uD808[\uDF9A-\uDFFF]|\uD809[\uDC6F-\uDC7F\uDD44-\uDFFF]|[\uD80A\uD80B\uD80E-\uD810\uD812-\uD819\uD824-\uD82B\uD82D\uD82E\uD830-\uD833\uD837\uD839\uD83D\uD83F\uD87B-\uD87D\uD87F\uD885-\uDB3F\uDB41-\uDBFF][\uDC00-\uDFFF]|\uD80D[\uDC2F-\uDFFF]|\uD811[\uDE47-\uDFFF]|\uD81A[\uDE39-\uDE3F\uDE5F\uDE6A-\uDECF\uDEEE\uDEEF\uDEF5-\uDEFF\uDF37-\uDF3F\uDF44-\uDF4F\uDF5A-\uDF62\uDF78-\uDF7C\uDF90-\uDFFF]|\uD81B[\uDC00-\uDE3F\uDE80-\uDEFF\uDF4B-\uDF4E\uDF88-\uDF8E\uDFA0-\uDFDF\uDFE2\uDFE5-\uDFEF\uDFF2-\uDFFF]|\uD821[\uDFF8-\uDFFF]|\uD823[\uDCD6-\uDCFF\uDD09-\uDFFF]|\uD82C[\uDD1F-\uDD4F\uDD53-\uDD63\uDD68-\uDD6F\uDEFC-\uDFFF]|\uD82F[\uDC6B-\uDC6F\uDC7D-\uDC7F\uDC89-\uDC8F\uDC9A-\uDC9C\uDC9F-\uDFFF]|\uD834[\uDC00-\uDD64\uDD6A-\uDD6C\uDD73-\uDD7A\uDD83\uDD84\uDD8C-\uDDA9\uDDAE-\uDE41\uDE45-\uDFFF]|\uD835[\uDC55\uDC9D\uDCA0\uDCA1\uDCA3\uDCA4\uDCA7\uDCA8\uDCAD\uDCBA\uDCBC\uDCC4\uDD06\uDD0B\uDD0C\uDD15\uDD1D\uDD3A\uDD3F\uDD45\uDD47-\uDD49\uDD51\uDEA6\uDEA7\uDEC1\uDEDB\uDEFB\uDF15\uDF35\uDF4F\uDF6F\uDF89\uDFA9\uDFC3\uDFCC\uDFCD]|\uD836[\uDC00-\uDDFF\uDE37-\uDE3A\uDE6D-\uDE74\uDE76-\uDE83\uDE85-\uDE9A\uDEA0\uDEB0-\uDFFF]|\uD838[\uDC07\uDC19\uDC1A\uDC22\uDC25\uDC2B-\uDCFF\uDD2D-\uDD2F\uDD3E\uDD3F\uDD4A-\uDD4D\uDD4F-\uDEBF\uDEFA-\uDFFF]|\uD83A[\uDCC5-\uDCCF\uDCD7-\uDCFF\uDD4C-\uDD4F\uDD5A-\uDFFF]|\uD83B[\uDC00-\uDDFF\uDE04\uDE20\uDE23\uDE25\uDE26\uDE28\uDE33\uDE38\uDE3A\uDE3C-\uDE41\uDE43-\uDE46\uDE48\uDE4A\uDE4C\uDE50\uDE53\uDE55\uDE56\uDE58\uDE5A\uDE5C\uDE5E\uDE60\uDE63\uDE65\uDE66\uDE6B\uDE73\uDE78\uDE7D\uDE7F\uDE8A\uDE9C-\uDEA0\uDEA4\uDEAA\uDEBC-\uDFFF]|\uD83C[\uDC00-\uDD2F\uDD4A-\uDD4F\uDD6A-\uDD6F\uDD8A-\uDFFF]|\uD83E[\uDC00-\uDFEF\uDFFA-\uDFFF]|\uD869[\uDEDE-\uDEFF]|\uD86D[\uDF35-\uDF3F]|\uD86E[\uDC1E\uDC1F]|\uD873[\uDEA2-\uDEAF]|\uD87A[\uDFE1-\uDFFF]|\uD87E[\uDE1E-\uDFFF]|\uD884[\uDF4B-\uDFFF]|\uDB40[\uDC00-\uDCFF\uDDF0-\uDFFF]/g;
639
- function slug(value, maintainCase) {
640
- if (typeof value !== "string") return "";
641
- value = value.toLowerCase();
642
- return value.replace(regex, "").replace(/ /g, "-");
643
- }
644
-
645
637
  // node_modules/preact/dist/preact.mjs
646
638
  var n;
647
639
  var l;
@@ -681,6 +673,12 @@ function u2(e2, t2, n2, o2, i2, u3) {
681
673
  }
682
674
 
683
675
  // node_modules/@quartz-community/utils/dist/index.js
676
+ var regex = /[\0-\x1F!-,\.\/:-@\[-\^`\{-\xA9\xAB-\xB4\xB6-\xB9\xBB-\xBF\xD7\xF7\u02C2-\u02C5\u02D2-\u02DF\u02E5-\u02EB\u02ED\u02EF-\u02FF\u0375\u0378\u0379\u037E\u0380-\u0385\u0387\u038B\u038D\u03A2\u03F6\u0482\u0530\u0557\u0558\u055A-\u055F\u0589-\u0590\u05BE\u05C0\u05C3\u05C6\u05C8-\u05CF\u05EB-\u05EE\u05F3-\u060F\u061B-\u061F\u066A-\u066D\u06D4\u06DD\u06DE\u06E9\u06FD\u06FE\u0700-\u070F\u074B\u074C\u07B2-\u07BF\u07F6-\u07F9\u07FB\u07FC\u07FE\u07FF\u082E-\u083F\u085C-\u085F\u086B-\u089F\u08B5\u08C8-\u08D2\u08E2\u0964\u0965\u0970\u0984\u098D\u098E\u0991\u0992\u09A9\u09B1\u09B3-\u09B5\u09BA\u09BB\u09C5\u09C6\u09C9\u09CA\u09CF-\u09D6\u09D8-\u09DB\u09DE\u09E4\u09E5\u09F2-\u09FB\u09FD\u09FF\u0A00\u0A04\u0A0B-\u0A0E\u0A11\u0A12\u0A29\u0A31\u0A34\u0A37\u0A3A\u0A3B\u0A3D\u0A43-\u0A46\u0A49\u0A4A\u0A4E-\u0A50\u0A52-\u0A58\u0A5D\u0A5F-\u0A65\u0A76-\u0A80\u0A84\u0A8E\u0A92\u0AA9\u0AB1\u0AB4\u0ABA\u0ABB\u0AC6\u0ACA\u0ACE\u0ACF\u0AD1-\u0ADF\u0AE4\u0AE5\u0AF0-\u0AF8\u0B00\u0B04\u0B0D\u0B0E\u0B11\u0B12\u0B29\u0B31\u0B34\u0B3A\u0B3B\u0B45\u0B46\u0B49\u0B4A\u0B4E-\u0B54\u0B58-\u0B5B\u0B5E\u0B64\u0B65\u0B70\u0B72-\u0B81\u0B84\u0B8B-\u0B8D\u0B91\u0B96-\u0B98\u0B9B\u0B9D\u0BA0-\u0BA2\u0BA5-\u0BA7\u0BAB-\u0BAD\u0BBA-\u0BBD\u0BC3-\u0BC5\u0BC9\u0BCE\u0BCF\u0BD1-\u0BD6\u0BD8-\u0BE5\u0BF0-\u0BFF\u0C0D\u0C11\u0C29\u0C3A-\u0C3C\u0C45\u0C49\u0C4E-\u0C54\u0C57\u0C5B-\u0C5F\u0C64\u0C65\u0C70-\u0C7F\u0C84\u0C8D\u0C91\u0CA9\u0CB4\u0CBA\u0CBB\u0CC5\u0CC9\u0CCE-\u0CD4\u0CD7-\u0CDD\u0CDF\u0CE4\u0CE5\u0CF0\u0CF3-\u0CFF\u0D0D\u0D11\u0D45\u0D49\u0D4F-\u0D53\u0D58-\u0D5E\u0D64\u0D65\u0D70-\u0D79\u0D80\u0D84\u0D97-\u0D99\u0DB2\u0DBC\u0DBE\u0DBF\u0DC7-\u0DC9\u0DCB-\u0DCE\u0DD5\u0DD7\u0DE0-\u0DE5\u0DF0\u0DF1\u0DF4-\u0E00\u0E3B-\u0E3F\u0E4F\u0E5A-\u0E80\u0E83\u0E85\u0E8B\u0EA4\u0EA6\u0EBE\u0EBF\u0EC5\u0EC7\u0ECE\u0ECF\u0EDA\u0EDB\u0EE0-\u0EFF\u0F01-\u0F17\u0F1A-\u0F1F\u0F2A-\u0F34\u0F36\u0F38\u0F3A-\u0F3D\u0F48\u0F6D-\u0F70\u0F85\u0F98\u0FBD-\u0FC5\u0FC7-\u0FFF\u104A-\u104F\u109E\u109F\u10C6\u10C8-\u10CC\u10CE\u10CF\u10FB\u1249\u124E\u124F\u1257\u1259\u125E\u125F\u1289\u128E\u128F\u12B1\u12B6\u12B7\u12BF\u12C1\u12C6\u12C7\u12D7\u1311\u1316\u1317\u135B\u135C\u1360-\u137F\u1390-\u139F\u13F6\u13F7\u13FE-\u1400\u166D\u166E\u1680\u169B-\u169F\u16EB-\u16ED\u16F9-\u16FF\u170D\u1715-\u171F\u1735-\u173F\u1754-\u175F\u176D\u1771\u1774-\u177F\u17D4-\u17D6\u17D8-\u17DB\u17DE\u17DF\u17EA-\u180A\u180E\u180F\u181A-\u181F\u1879-\u187F\u18AB-\u18AF\u18F6-\u18FF\u191F\u192C-\u192F\u193C-\u1945\u196E\u196F\u1975-\u197F\u19AC-\u19AF\u19CA-\u19CF\u19DA-\u19FF\u1A1C-\u1A1F\u1A5F\u1A7D\u1A7E\u1A8A-\u1A8F\u1A9A-\u1AA6\u1AA8-\u1AAF\u1AC1-\u1AFF\u1B4C-\u1B4F\u1B5A-\u1B6A\u1B74-\u1B7F\u1BF4-\u1BFF\u1C38-\u1C3F\u1C4A-\u1C4C\u1C7E\u1C7F\u1C89-\u1C8F\u1CBB\u1CBC\u1CC0-\u1CCF\u1CD3\u1CFB-\u1CFF\u1DFA\u1F16\u1F17\u1F1E\u1F1F\u1F46\u1F47\u1F4E\u1F4F\u1F58\u1F5A\u1F5C\u1F5E\u1F7E\u1F7F\u1FB5\u1FBD\u1FBF-\u1FC1\u1FC5\u1FCD-\u1FCF\u1FD4\u1FD5\u1FDC-\u1FDF\u1FED-\u1FF1\u1FF5\u1FFD-\u203E\u2041-\u2053\u2055-\u2070\u2072-\u207E\u2080-\u208F\u209D-\u20CF\u20F1-\u2101\u2103-\u2106\u2108\u2109\u2114\u2116-\u2118\u211E-\u2123\u2125\u2127\u2129\u212E\u213A\u213B\u2140-\u2144\u214A-\u214D\u214F-\u215F\u2189-\u24B5\u24EA-\u2BFF\u2C2F\u2C5F\u2CE5-\u2CEA\u2CF4-\u2CFF\u2D26\u2D28-\u2D2C\u2D2E\u2D2F\u2D68-\u2D6E\u2D70-\u2D7E\u2D97-\u2D9F\u2DA7\u2DAF\u2DB7\u2DBF\u2DC7\u2DCF\u2DD7\u2DDF\u2E00-\u2E2E\u2E30-\u3004\u3008-\u3020\u3030\u3036\u3037\u303D-\u3040\u3097\u3098\u309B\u309C\u30A0\u30FB\u3100-\u3104\u3130\u318F-\u319F\u31C0-\u31EF\u3200-\u33FF\u4DC0-\u4DFF\u9FFD-\u9FFF\uA48D-\uA4CF\uA4FE\uA4FF\uA60D-\uA60F\uA62C-\uA63F\uA673\uA67E\uA6F2-\uA716\uA720\uA721\uA789\uA78A\uA7C0\uA7C1\uA7CB-\uA7F4\uA828-\uA82B\uA82D-\uA83F\uA874-\uA87F\uA8C6-\uA8CF\uA8DA-\uA8DF\uA8F8-\uA8FA\uA8FC\uA92E\uA92F\uA954-\uA95F\uA97D-\uA97F\uA9C1-\uA9CE\uA9DA-\uA9DF\uA9FF\uAA37-\uAA3F\uAA4E\uAA4F\uAA5A-\uAA5F\uAA77-\uAA79\uAAC3-\uAADA\uAADE\uAADF\uAAF0\uAAF1\uAAF7-\uAB00\uAB07\uAB08\uAB0F\uAB10\uAB17-\uAB1F\uAB27\uAB2F\uAB5B\uAB6A-\uAB6F\uABEB\uABEE\uABEF\uABFA-\uABFF\uD7A4-\uD7AF\uD7C7-\uD7CA\uD7FC-\uD7FF\uE000-\uF8FF\uFA6E\uFA6F\uFADA-\uFAFF\uFB07-\uFB12\uFB18-\uFB1C\uFB29\uFB37\uFB3D\uFB3F\uFB42\uFB45\uFBB2-\uFBD2\uFD3E-\uFD4F\uFD90\uFD91\uFDC8-\uFDEF\uFDFC-\uFDFF\uFE10-\uFE1F\uFE30-\uFE32\uFE35-\uFE4C\uFE50-\uFE6F\uFE75\uFEFD-\uFF0F\uFF1A-\uFF20\uFF3B-\uFF3E\uFF40\uFF5B-\uFF65\uFFBF-\uFFC1\uFFC8\uFFC9\uFFD0\uFFD1\uFFD8\uFFD9\uFFDD-\uFFFF]|\uD800[\uDC0C\uDC27\uDC3B\uDC3E\uDC4E\uDC4F\uDC5E-\uDC7F\uDCFB-\uDD3F\uDD75-\uDDFC\uDDFE-\uDE7F\uDE9D-\uDE9F\uDED1-\uDEDF\uDEE1-\uDEFF\uDF20-\uDF2C\uDF4B-\uDF4F\uDF7B-\uDF7F\uDF9E\uDF9F\uDFC4-\uDFC7\uDFD0\uDFD6-\uDFFF]|\uD801[\uDC9E\uDC9F\uDCAA-\uDCAF\uDCD4-\uDCD7\uDCFC-\uDCFF\uDD28-\uDD2F\uDD64-\uDDFF\uDF37-\uDF3F\uDF56-\uDF5F\uDF68-\uDFFF]|\uD802[\uDC06\uDC07\uDC09\uDC36\uDC39-\uDC3B\uDC3D\uDC3E\uDC56-\uDC5F\uDC77-\uDC7F\uDC9F-\uDCDF\uDCF3\uDCF6-\uDCFF\uDD16-\uDD1F\uDD3A-\uDD7F\uDDB8-\uDDBD\uDDC0-\uDDFF\uDE04\uDE07-\uDE0B\uDE14\uDE18\uDE36\uDE37\uDE3B-\uDE3E\uDE40-\uDE5F\uDE7D-\uDE7F\uDE9D-\uDEBF\uDEC8\uDEE7-\uDEFF\uDF36-\uDF3F\uDF56-\uDF5F\uDF73-\uDF7F\uDF92-\uDFFF]|\uD803[\uDC49-\uDC7F\uDCB3-\uDCBF\uDCF3-\uDCFF\uDD28-\uDD2F\uDD3A-\uDE7F\uDEAA\uDEAD-\uDEAF\uDEB2-\uDEFF\uDF1D-\uDF26\uDF28-\uDF2F\uDF51-\uDFAF\uDFC5-\uDFDF\uDFF7-\uDFFF]|\uD804[\uDC47-\uDC65\uDC70-\uDC7E\uDCBB-\uDCCF\uDCE9-\uDCEF\uDCFA-\uDCFF\uDD35\uDD40-\uDD43\uDD48-\uDD4F\uDD74\uDD75\uDD77-\uDD7F\uDDC5-\uDDC8\uDDCD\uDDDB\uDDDD-\uDDFF\uDE12\uDE38-\uDE3D\uDE3F-\uDE7F\uDE87\uDE89\uDE8E\uDE9E\uDEA9-\uDEAF\uDEEB-\uDEEF\uDEFA-\uDEFF\uDF04\uDF0D\uDF0E\uDF11\uDF12\uDF29\uDF31\uDF34\uDF3A\uDF45\uDF46\uDF49\uDF4A\uDF4E\uDF4F\uDF51-\uDF56\uDF58-\uDF5C\uDF64\uDF65\uDF6D-\uDF6F\uDF75-\uDFFF]|\uD805[\uDC4B-\uDC4F\uDC5A-\uDC5D\uDC62-\uDC7F\uDCC6\uDCC8-\uDCCF\uDCDA-\uDD7F\uDDB6\uDDB7\uDDC1-\uDDD7\uDDDE-\uDDFF\uDE41-\uDE43\uDE45-\uDE4F\uDE5A-\uDE7F\uDEB9-\uDEBF\uDECA-\uDEFF\uDF1B\uDF1C\uDF2C-\uDF2F\uDF3A-\uDFFF]|\uD806[\uDC3B-\uDC9F\uDCEA-\uDCFE\uDD07\uDD08\uDD0A\uDD0B\uDD14\uDD17\uDD36\uDD39\uDD3A\uDD44-\uDD4F\uDD5A-\uDD9F\uDDA8\uDDA9\uDDD8\uDDD9\uDDE2\uDDE5-\uDDFF\uDE3F-\uDE46\uDE48-\uDE4F\uDE9A-\uDE9C\uDE9E-\uDEBF\uDEF9-\uDFFF]|\uD807[\uDC09\uDC37\uDC41-\uDC4F\uDC5A-\uDC71\uDC90\uDC91\uDCA8\uDCB7-\uDCFF\uDD07\uDD0A\uDD37-\uDD39\uDD3B\uDD3E\uDD48-\uDD4F\uDD5A-\uDD5F\uDD66\uDD69\uDD8F\uDD92\uDD99-\uDD9F\uDDAA-\uDEDF\uDEF7-\uDFAF\uDFB1-\uDFFF]|\uD808[\uDF9A-\uDFFF]|\uD809[\uDC6F-\uDC7F\uDD44-\uDFFF]|[\uD80A\uD80B\uD80E-\uD810\uD812-\uD819\uD824-\uD82B\uD82D\uD82E\uD830-\uD833\uD837\uD839\uD83D\uD83F\uD87B-\uD87D\uD87F\uD885-\uDB3F\uDB41-\uDBFF][\uDC00-\uDFFF]|\uD80D[\uDC2F-\uDFFF]|\uD811[\uDE47-\uDFFF]|\uD81A[\uDE39-\uDE3F\uDE5F\uDE6A-\uDECF\uDEEE\uDEEF\uDEF5-\uDEFF\uDF37-\uDF3F\uDF44-\uDF4F\uDF5A-\uDF62\uDF78-\uDF7C\uDF90-\uDFFF]|\uD81B[\uDC00-\uDE3F\uDE80-\uDEFF\uDF4B-\uDF4E\uDF88-\uDF8E\uDFA0-\uDFDF\uDFE2\uDFE5-\uDFEF\uDFF2-\uDFFF]|\uD821[\uDFF8-\uDFFF]|\uD823[\uDCD6-\uDCFF\uDD09-\uDFFF]|\uD82C[\uDD1F-\uDD4F\uDD53-\uDD63\uDD68-\uDD6F\uDEFC-\uDFFF]|\uD82F[\uDC6B-\uDC6F\uDC7D-\uDC7F\uDC89-\uDC8F\uDC9A-\uDC9C\uDC9F-\uDFFF]|\uD834[\uDC00-\uDD64\uDD6A-\uDD6C\uDD73-\uDD7A\uDD83\uDD84\uDD8C-\uDDA9\uDDAE-\uDE41\uDE45-\uDFFF]|\uD835[\uDC55\uDC9D\uDCA0\uDCA1\uDCA3\uDCA4\uDCA7\uDCA8\uDCAD\uDCBA\uDCBC\uDCC4\uDD06\uDD0B\uDD0C\uDD15\uDD1D\uDD3A\uDD3F\uDD45\uDD47-\uDD49\uDD51\uDEA6\uDEA7\uDEC1\uDEDB\uDEFB\uDF15\uDF35\uDF4F\uDF6F\uDF89\uDFA9\uDFC3\uDFCC\uDFCD]|\uD836[\uDC00-\uDDFF\uDE37-\uDE3A\uDE6D-\uDE74\uDE76-\uDE83\uDE85-\uDE9A\uDEA0\uDEB0-\uDFFF]|\uD838[\uDC07\uDC19\uDC1A\uDC22\uDC25\uDC2B-\uDCFF\uDD2D-\uDD2F\uDD3E\uDD3F\uDD4A-\uDD4D\uDD4F-\uDEBF\uDEFA-\uDFFF]|\uD83A[\uDCC5-\uDCCF\uDCD7-\uDCFF\uDD4C-\uDD4F\uDD5A-\uDFFF]|\uD83B[\uDC00-\uDDFF\uDE04\uDE20\uDE23\uDE25\uDE26\uDE28\uDE33\uDE38\uDE3A\uDE3C-\uDE41\uDE43-\uDE46\uDE48\uDE4A\uDE4C\uDE50\uDE53\uDE55\uDE56\uDE58\uDE5A\uDE5C\uDE5E\uDE60\uDE63\uDE65\uDE66\uDE6B\uDE73\uDE78\uDE7D\uDE7F\uDE8A\uDE9C-\uDEA0\uDEA4\uDEAA\uDEBC-\uDFFF]|\uD83C[\uDC00-\uDD2F\uDD4A-\uDD4F\uDD6A-\uDD6F\uDD8A-\uDFFF]|\uD83E[\uDC00-\uDFEF\uDFFA-\uDFFF]|\uD869[\uDEDE-\uDEFF]|\uD86D[\uDF35-\uDF3F]|\uD86E[\uDC1E\uDC1F]|\uD873[\uDEA2-\uDEAF]|\uD87A[\uDFE1-\uDFFF]|\uD87E[\uDE1E-\uDFFF]|\uD884[\uDF4B-\uDFFF]|\uDB40[\uDC00-\uDCFF\uDDF0-\uDFFF]/g;
677
+ function slug(value, maintainCase) {
678
+ if (typeof value !== "string") return "";
679
+ value = value.toLowerCase();
680
+ return value.replace(regex, "").replace(/ /g, "-");
681
+ }
684
682
  function simplifySlug(fp) {
685
683
  const res = stripSlashes(trimSuffix(fp, "index"), true);
686
684
  return res.length === 0 ? "/" : res;
@@ -751,6 +749,9 @@ function resolveRelative(current, target) {
751
749
  const res = joinSegments(pathToRoot(current), simplifySlug(target));
752
750
  return res;
753
751
  }
752
+ function slugHeading(text) {
753
+ return slug(text);
754
+ }
754
755
  function splitAnchor(link) {
755
756
  const [fp, anchor] = link.split("#", 2);
756
757
  if (fp.endsWith(".pdf")) {
@@ -760,7 +761,7 @@ function splitAnchor(link) {
760
761
  return [fp, ""];
761
762
  }
762
763
  const bare = anchor.startsWith("^") ? anchor.slice(1) : anchor;
763
- const slugged = "#" + slug(bare);
764
+ const slugged = "#" + slugHeading(bare);
764
765
  return [fp, slugged];
765
766
  }
766
767
  function transformInternalLink(link) {
@@ -779,7 +780,7 @@ function transformInternalLink(link) {
779
780
  function transformLink(src, target, opts) {
780
781
  const targetSlug = transformInternalLink(target);
781
782
  if (opts.strategy === "relative") {
782
- return targetSlug;
783
+ return _resolveRelativeFolderNote(src, target) ?? targetSlug;
783
784
  } else {
784
785
  const effectiveSrc = !endsWith(src, "index") && opts.allSlugs.includes(`${src}/index`) ? `${src}/index` : src;
785
786
  const folderTail = isFolderPath(targetSlug) ? "/" : "";
@@ -788,7 +789,7 @@ function transformLink(src, target, opts) {
788
789
  if (opts.strategy === "shortest") {
789
790
  const isMultiSegment = targetCanonical.includes("/");
790
791
  const isFolderTarget = isFolderPath(targetSlug);
791
- const matchingFileNames = opts.allSlugs.filter((slug2) => {
792
+ let matchingFileNames = opts.allSlugs.filter((slug2) => {
792
793
  if (isMultiSegment) {
793
794
  if (slug2 === targetCanonical || slug2.endsWith("/" + targetCanonical)) {
794
795
  return true;
@@ -803,6 +804,12 @@ function transformLink(src, target, opts) {
803
804
  const fileName = parts.at(-1);
804
805
  return targetCanonical === fileName;
805
806
  });
807
+ if (matchingFileNames.length === 0 && !isMultiSegment) {
808
+ matchingFileNames = opts.allSlugs.filter((slug2) => {
809
+ const parts = slug2.split("/");
810
+ return parts.at(-1) === "index" && parts.at(-2) === targetCanonical;
811
+ });
812
+ }
806
813
  if (matchingFileNames.length === 1) {
807
814
  const matchedSlug = matchingFileNames[0];
808
815
  return resolveRelative(effectiveSrc, matchedSlug) + targetAnchor;
@@ -811,6 +818,37 @@ function transformLink(src, target, opts) {
811
818
  return joinSegments(pathToRoot(effectiveSrc), canonicalSlug) + folderTail;
812
819
  }
813
820
  }
821
+ function _resolveRelativeFolderNote(src, target) {
822
+ let decoded;
823
+ try {
824
+ decoded = decodeURI(target);
825
+ } catch {
826
+ return void 0;
827
+ }
828
+ const hashIdx = decoded.indexOf("#");
829
+ const fplike = hashIdx === -1 ? decoded : decoded.slice(0, hashIdx);
830
+ const rest = hashIdx === -1 ? "" : decoded.slice(hashIdx);
831
+ if (fplike === "" || fplike.endsWith("/") || fplike.startsWith("/")) return void 0;
832
+ const ext = getFileExtension(fplike);
833
+ if (![".md", ".html", void 0].includes(ext)) return void 0;
834
+ const segments = fplike.split("/");
835
+ const fileName = segments[segments.length - 1];
836
+ const fileSlug = slugifyPath(ext ? fileName.slice(0, -ext.length) : fileName);
837
+ if (fileSlug === "index") return void 0;
838
+ const resolved = src.split("/").slice(0, -1);
839
+ for (const seg of segments.slice(0, -1)) {
840
+ if (seg === "" || seg === ".") continue;
841
+ if (seg === "..") {
842
+ if (resolved.length === 0) return void 0;
843
+ resolved.pop();
844
+ } else {
845
+ resolved.push(slugifyPath(seg));
846
+ }
847
+ }
848
+ if (resolved.length === 0 || resolved[resolved.length - 1] !== fileSlug) return void 0;
849
+ segments[segments.length - 1] = "index" + (ext ?? "");
850
+ return transformInternalLink(encodeURI(segments.join("/") + rest));
851
+ }
814
852
  function slugifyPath(s2) {
815
853
  return s2.split("/").map(
816
854
  (segment) => segment.replace(/\s/g, "-").replace(/&/g, "-and-").replace(/%/g, "-percent").replace(/\?/g, "").replace(/#/g, "").replace(/[<>:"|*]/g, "").toLowerCase()
@@ -916,12 +954,9 @@ function resolveSelfPath(value) {
916
954
  function listContainsName(list, name, selfPath) {
917
955
  const slugName = slugifyPath(name);
918
956
  const selfSlug = selfPath ? slugifyFilePath(selfPath) : null;
919
- return list.some((item) => {
920
- if (typeof item !== "string") return false;
921
- const match = item.match(/^\[\[([^\]|]+)(?:\|[^\]]+)?\]\]$/);
922
- if (match?.[1]) {
923
- return match[1] === name || match[1].endsWith(`/${name}`);
924
- }
957
+ return list.some((value) => {
958
+ if (typeof value !== "string") return false;
959
+ const item = parseWikilink(value)?.target.replace(/\.md$/, "") ?? value;
925
960
  if (item === name) return true;
926
961
  const slugItem = slugifyPath(item);
927
962
  if (slugItem === slugName || slugItem.endsWith(`/${slugName}`)) return true;
@@ -1028,6 +1063,18 @@ function parseDate(value) {
1028
1063
  }
1029
1064
  return void 0;
1030
1065
  }
1066
+ function parseWikilink(value) {
1067
+ const match = /^\[\[([^|#\]]+)(#[^|\]]*)?(?:\|[^\]]*)?\]\]$/.exec(value.trim());
1068
+ const target = match?.[1]?.trim();
1069
+ if (!match || !target) return null;
1070
+ return { target, subpath: match[2] ?? "" };
1071
+ }
1072
+ function linkTarget(value) {
1073
+ if (isFileValue(value)) return value.path.replace(/\.md$/, "");
1074
+ const raw = toStringValue(value);
1075
+ const wikilink = parseWikilink(raw);
1076
+ return wikilink ? `${wikilink.target}${wikilink.subpath}` : raw;
1077
+ }
1031
1078
  function buildFileValue(path) {
1032
1079
  const normalized = path.trim();
1033
1080
  const lastSlash = normalized.lastIndexOf("/");
@@ -1046,6 +1093,44 @@ function buildFileValue(path) {
1046
1093
  links: []
1047
1094
  };
1048
1095
  }
1096
+ function lookupFile(path, context) {
1097
+ const lookup = context._fileLookup;
1098
+ if (!lookup) return void 0;
1099
+ const normalized = path.trim();
1100
+ if (!normalized) return void 0;
1101
+ const found = lookup.get(normalized) ?? lookup.get(normalized.replace(/\.md$/, "")) ?? (!normalized.endsWith(".md") ? lookup.get(`${normalized}.md`) : void 0);
1102
+ if (found) return found;
1103
+ const suffix = `/${normalized}`;
1104
+ const suffixMd = `/${normalized}.md`;
1105
+ for (const [key, value] of lookup) {
1106
+ if (key.endsWith(suffix) || key.endsWith(suffixMd)) return value;
1107
+ }
1108
+ return void 0;
1109
+ }
1110
+ function resolveLink(value, context) {
1111
+ if (typeof value !== "string") return null;
1112
+ const wikilink = parseWikilink(value);
1113
+ if (!wikilink) return null;
1114
+ const path = lookupFile(wikilink.target, context)?.path ?? wikilink.target;
1115
+ const fileName = path.slice(path.lastIndexOf("/") + 1);
1116
+ return { name: fileName.replace(/\.md$/, ""), path };
1117
+ }
1118
+ function sameLinkTarget(left, right) {
1119
+ return slugifyFilePath(left.path.trim()) === slugifyFilePath(right.path.trim());
1120
+ }
1121
+ function listContains(list, needle, context) {
1122
+ if (list.includes(needle)) return true;
1123
+ if (needle === void 0 || needle === null) return false;
1124
+ const link = resolveLink(needle, context);
1125
+ if (link) return listContainsName(list, link.name, link.path);
1126
+ if (typeof needle === "string") {
1127
+ const slugNeedle = slugifyPath(needle);
1128
+ if (list.some((item) => typeof item === "string" && slugifyPath(item) === slugNeedle))
1129
+ return true;
1130
+ }
1131
+ const name = resolveSelfName(needle);
1132
+ return name ? listContainsName(list, name, resolveSelfPath(needle)) : false;
1133
+ }
1049
1134
  function getMethodTarget(value) {
1050
1135
  if (typeof value === "string") return "string";
1051
1136
  if (typeof value === "number" && !Number.isNaN(value)) return "number";
@@ -1058,13 +1143,9 @@ function getMethodTarget(value) {
1058
1143
  registerGlobalFunction("if", ([cond, whenTrue, whenFalse]) => {
1059
1144
  return cond ? whenTrue : whenFalse;
1060
1145
  });
1061
- registerGlobalFunction("contains", ([haystack, needle]) => {
1062
- if (Array.isArray(haystack)) {
1063
- if (haystack.includes(needle)) return true;
1064
- const name = resolveSelfName(needle);
1065
- return name ? listContainsName(haystack, name, resolveSelfPath(needle)) : false;
1066
- }
1067
- if (typeof haystack === "string") return haystack.includes(toStringValue(needle));
1146
+ registerGlobalFunction("contains", ([haystack, needle], context) => {
1147
+ if (Array.isArray(haystack)) return listContains(haystack, needle, context);
1148
+ if (typeof haystack === "string") return stringContains(haystack, needle, context);
1068
1149
  return false;
1069
1150
  });
1070
1151
  registerGlobalFunction("date", ([value]) => parseDate(value));
@@ -1098,7 +1179,7 @@ registerGlobalFunction("list", ([value]) => {
1098
1179
  return [value];
1099
1180
  });
1100
1181
  registerGlobalFunction("link", ([path, display]) => {
1101
- const target = isFileValue(path) ? path.path.replace(/\.md$/, "") : toStringValue(path);
1182
+ const target = linkTarget(path);
1102
1183
  if (!target) return "";
1103
1184
  const label = isFileValue(display) ? display.basename : toStringValue(display);
1104
1185
  return label ? `[[${target}|${label}]]` : `[[${target}]]`;
@@ -1144,9 +1225,9 @@ registerMethodFunction("file", "hasLink", (target, [link]) => {
1144
1225
  });
1145
1226
  registerMethodFunction("file", "inFolder", (target, [folder]) => {
1146
1227
  if (!isFileValue(target)) return false;
1147
- const value = toStringValue(folder);
1148
- if (!value) return false;
1149
- const normalized = value.endsWith("/") ? value.slice(0, -1) : value;
1228
+ if (typeof folder !== "string") return false;
1229
+ const normalized = folder.trim().replace(/^\/+|\/+$/g, "");
1230
+ if (normalized === "") return true;
1150
1231
  return target.folder === normalized || target.folder.startsWith(`${normalized}/`);
1151
1232
  });
1152
1233
  registerMethodFunction("file", "hasProperty", (_target, [prop], context) => {
@@ -1161,10 +1242,19 @@ registerMethodFunction("file", "hasProperty", (_target, [prop], context) => {
1161
1242
  }
1162
1243
  return true;
1163
1244
  });
1164
- registerMethodFunction("string", "contains", (target, [needle]) => {
1245
+ function stringContains(target, needle, context) {
1246
+ if (needle === void 0 || needle === null) return false;
1165
1247
  const value = toStringValue(target);
1248
+ const needleLink = resolveLink(needle, context);
1249
+ const valueLink = needleLink ? resolveLink(value, context) : null;
1250
+ if (needleLink && valueLink && sameLinkTarget(valueLink, needleLink)) return true;
1166
1251
  return value.includes(toStringValue(needle));
1167
- });
1252
+ }
1253
+ registerMethodFunction(
1254
+ "string",
1255
+ "contains",
1256
+ (target, [needle], context) => stringContains(target, needle, context)
1257
+ );
1168
1258
  registerMethodFunction("string", "startsWith", (target, [prefix]) => {
1169
1259
  const value = toStringValue(target);
1170
1260
  return value.startsWith(toStringValue(prefix));
@@ -1434,33 +1524,15 @@ registerMethodFunction("string", "title", (target) => {
1434
1524
  return value.replace(/\b\w/g, (ch) => ch.toUpperCase());
1435
1525
  });
1436
1526
  registerMethodFunction("string", "asFile", (target, _args, context) => {
1437
- const path = toStringValue(target);
1527
+ const raw = toStringValue(target);
1528
+ const path = parseWikilink(raw)?.target ?? raw;
1438
1529
  if (!path) return void 0;
1439
- const lookup = context._fileLookup;
1440
- if (lookup) {
1441
- const normalized = path.trim();
1442
- const found = lookup.get(normalized) ?? lookup.get(normalized.replace(/\.md$/, "")) ?? (!normalized.endsWith(".md") ? lookup.get(`${normalized}.md`) : void 0);
1443
- if (found) return { ...found };
1444
- const suffix = `/${normalized}`;
1445
- const suffixMd = `/${normalized}.md`;
1446
- for (const [key, value] of lookup) {
1447
- if (key.endsWith(suffix) || key.endsWith(suffixMd)) {
1448
- return { ...value };
1449
- }
1450
- }
1451
- }
1452
- return buildFileValue(path);
1530
+ const found = lookupFile(path, context);
1531
+ return found ? { ...found } : buildFileValue(path);
1453
1532
  });
1454
- registerMethodFunction("list", "contains", (target, [needle]) => {
1533
+ registerMethodFunction("list", "contains", (target, [needle], context) => {
1455
1534
  if (!Array.isArray(target)) return false;
1456
- if (target.includes(needle)) return true;
1457
- if (typeof needle === "string") {
1458
- const slugNeedle = slugifyPath(needle);
1459
- if (target.some((item) => typeof item === "string" && slugifyPath(item) === slugNeedle))
1460
- return true;
1461
- }
1462
- const name = resolveSelfName(needle);
1463
- return name ? listContainsName(target, name, resolveSelfPath(needle)) : false;
1535
+ return listContains(target, needle, context);
1464
1536
  });
1465
1537
  registerMethodFunction("list", "containsAll", (target, args) => {
1466
1538
  if (!Array.isArray(target)) return false;
@@ -1966,5 +2038,5 @@ function evaluateFilter(node, context) {
1966
2038
  }
1967
2039
 
1968
2040
  export { S, compile, evaluate, evaluateFilter, k, l, resolvePropertyValue, slugifyFilePath, slugifyPath, transformLink, u2 as u };
1969
- //# sourceMappingURL=chunk-OBABVQK6.js.map
1970
- //# sourceMappingURL=chunk-OBABVQK6.js.map
2041
+ //# sourceMappingURL=chunk-4XYVHAYQ.js.map
2042
+ //# sourceMappingURL=chunk-4XYVHAYQ.js.map