From 2a505a24a8f4b289a4d119f8b7ad65d7bffdb3d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20R=C3=BCger?= Date: Fri, 13 Mar 2026 01:21:19 +0100 Subject: [PATCH] fix: parseLinks regex misses links at position 0 of string The previous pattern [^\!]\[...\] required exactly one non-! character before the opening bracket, so a markdown link at the very start of anchors to start-of-string or a non-! character without consuming a required preceding character. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- page/link.go | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/page/link.go b/page/link.go index 758ecd8..a2cb22e 100644 --- a/page/link.go +++ b/page/link.go @@ -185,8 +185,13 @@ func SubstituteLinks(markdown []byte, links []LinkSubstitution) []byte { } func parseLinks(markdown string) []markdownLink { - // Matches links but not inline images - re := regexp.MustCompile(`[^\!]\[.+\]\((([^\)#]+)?#?([^\)]+)?)\)`) + // Matches markdown links but not inline images (![ ... ]). + // Group 1: full link target (path + optional hash) + // Group 2: file path portion + // Group 3: hash portion + // The leading (?:^|[^!]) anchor prevents matching image syntax without + // consuming a character that belongs to a preceding link or word. + re := regexp.MustCompile(`(?:^|[^!])\[.+\]\((([^\)#]+)?#?([^\)]+)?)\)`) matches := re.FindAllStringSubmatch(markdown, -1) links := make([]markdownLink, len(matches))