Environment: graphifyy 0.9.53 (confirmed present in 0.9.52 too — regex is byte-for-byte identical between the two)
Summary
extractors/markdown.py's wikilink regex fails to extract two common Obsidian link forms, so any entity referenced only through them gets no graph edge:
_MD_WIKILINK_RE = re.compile(r'(?<!\!)\[\[([^\]|#]+)(?:[#|][^\]]*)?\]\]')
- A same-page anchor with no page name,
[[#Heading]], doesn't match at all — the capture group [^\]|#]+ requires at least one non-# character before hitting #, |, or ], and here # is the very first character.
- A cross-page anchored link,
[[Page#Heading|alias]], does match, but the non-capturing group (?:[#|][^\]]*)? throws away everything from the # or | onward — so the link resolves only to Page, never to the specific heading/section it points at.
Repro
import re
_MD_WIKILINK_RE = re.compile(r'(?<!\!)\[\[([^\]|#]+)(?:[#|][^\]]*)?\]\]')
print(_MD_WIKILINK_RE.search('[[#SomeHeading]]'))
# -> None (expected: a match resolving to the current file + "SomeHeading")
print(_MD_WIKILINK_RE.search('[[Other Page#SomeHeading|alias]]').group(1))
# -> 'Other Page' (expected: page="Other Page", heading="SomeHeading" — both available for resolution)
Impact
In a corpus where entities are extracted at sub-page granularity (one node per heading/struct/section rather than one node per file — common on reference-style docs), any entity referenced only via [[#Heading]] or [[Page#Heading]] links can never receive a syntactic (EXTRACTED) edge, because the regex can't preserve enough information to resolve to that specific node. On a ~1,100-node knowledge-graph build, this was one contributor to 133 nodes ending up with zero edges. It also silently breaks the [[#Heading]] same-page-anchor convention entirely, since those links aren't just under-resolved — they never enter the link list at all.
Suggested fix
Capture the heading fragment instead of discarding it, and allow an empty page-name group so pure anchor links match:
_MD_WIKILINK_RE = re.compile(r'(?<!\!)\[\[([^\]|#]*)(?:#([^\]|]*))?(?:\|[^\]]*)?\]\]')
- group(1): page name (empty string for a same-page anchor — caller should default to the current file)
- group(2): heading fragment, if any, for resolving to a sub-page node when the extractor supports that granularity
Happy to open a PR if that's welcome — wanted to confirm the intended resolution behaviour first (does the project have a concept of heading-level nodes it would want this to resolve to, or should #Heading just get ignored on purpose?).
Environment: graphifyy 0.9.53 (confirmed present in 0.9.52 too — regex is byte-for-byte identical between the two)
Summary
extractors/markdown.py's wikilink regex fails to extract two common Obsidian link forms, so any entity referenced only through them gets no graph edge:[[#Heading]], doesn't match at all — the capture group[^\]|#]+requires at least one non-#character before hitting#,|, or], and here#is the very first character.[[Page#Heading|alias]], does match, but the non-capturing group(?:[#|][^\]]*)?throws away everything from the#or|onward — so the link resolves only toPage, never to the specific heading/section it points at.Repro
Impact
In a corpus where entities are extracted at sub-page granularity (one node per heading/struct/section rather than one node per file — common on reference-style docs), any entity referenced only via
[[#Heading]]or[[Page#Heading]]links can never receive a syntactic (EXTRACTED) edge, because the regex can't preserve enough information to resolve to that specific node. On a ~1,100-node knowledge-graph build, this was one contributor to 133 nodes ending up with zero edges. It also silently breaks the[[#Heading]]same-page-anchor convention entirely, since those links aren't just under-resolved — they never enter the link list at all.Suggested fix
Capture the heading fragment instead of discarding it, and allow an empty page-name group so pure anchor links match:
Happy to open a PR if that's welcome — wanted to confirm the intended resolution behaviour first (does the project have a concept of heading-level nodes it would want this to resolve to, or should
#Headingjust get ignored on purpose?).