From 3e153a525c54bc7b9285c9a8f8b7834cfa9d3d1a Mon Sep 17 00:00:00 2001 From: Ohad Lutzky Date: Sat, 14 Dec 2024 08:19:25 +0000 Subject: [PATCH] Fix trailing periods for naked URLs (#1175) Fixes https://github.com/silverbulletmd/silverbullet/issues/1160 --- common/markdown_parser/parser.test.ts | 23 +++++++++++++++++++++++ common/markdown_parser/parser.ts | 2 +- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/common/markdown_parser/parser.test.ts b/common/markdown_parser/parser.test.ts index f763460e..0c11be0b 100644 --- a/common/markdown_parser/parser.test.ts +++ b/common/markdown_parser/parser.test.ts @@ -216,3 +216,26 @@ Deno.test("Test hashtag helper functions", () => { // should behave like this for all characters in tagRegex assertEquals(renderHashtag("exclamation!"), "#"); }); + +const nakedURLSample = ` +http://abc.com is a URL +Also http://no-trailing-period.com. That's a URL. It ends with m, not '.'. +http://no-trailing-comma.com, that same a URL, ends with m (and not ','). +http://trailing-slash.com/. That ends with '/' (still not '.'). +http://abc.com?e=2.71,pi=3.14 is a URL too. +http://abc.com?e=2.71. That is a URL, which ends with 1 (and not '.'). +`; + +Deno.test("Test NakedURL parser", () => { + const tree = parseMarkdown(nakedURLSample); + const urls = collectNodesOfType(tree, "NakedURL"); + + assertEquals(urls.map((x) => x.children![0].text), [ + "http://abc.com", + "http://no-trailing-period.com", + "http://no-trailing-comma.com", + "http://trailing-slash.com/", + "http://abc.com?e=2.71,pi=3.14", + "http://abc.com?e=2.71", + ]); +}); diff --git a/common/markdown_parser/parser.ts b/common/markdown_parser/parser.ts index d7c5e327..ce9f5c9c 100644 --- a/common/markdown_parser/parser.ts +++ b/common/markdown_parser/parser.ts @@ -577,7 +577,7 @@ const NakedURL = regexParser( { firstCharCode: 104, // h regex: - /^https?:\/\/[-a-zA-Z0-9@:%._\+~#=,;]{1,256}([-a-zA-Z0-9()@:%_\+.,;~#?&=\/]*)/, + /(^https?:\/\/([-a-zA-Z0-9@:%_\+~#=]|(?:[.](?!(\s|$)))){1,256})(([-a-zA-Z0-9(@:%_\+~#?&=\/]|(?:[.,:;)](?!(\s|$))))*)/, nodeType: "NakedURL", className: "sb-naked-url", tag: NakedURLTag,