Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions site/lib/lib.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -513,6 +513,8 @@ eq("bare url in bold", renderInline("**https://a.test/x**", passLink), '<strong>
eq("bare url keeps a balanced paren", renderInline("see https://a.test/wiki/Foo_(bar).", passLink), 'see <a href="https://a.test/wiki/Foo_(bar)" rel="noopener noreferrer">https://a.test/wiki/Foo_(bar)</a>.');
eq("angle-bracket autolink", renderInline("<https://a.test/x>", passLink), '<a href="https://a.test/x" rel="noopener noreferrer">https://a.test/x</a>');
eq("bare url stops at a code span", renderInline("https://a.test/x`y`", passLink), '<a href="https://a.test/x" rel="noopener noreferrer">https://a.test/x</a><code>y</code>');
eq("bare url stops at curly double quotes", renderInline("on “https://a.test/x”", passLink), 'on “<a href="https://a.test/x" rel="noopener noreferrer">https://a.test/x</a>”');
eq("bare url stops at curly single quotes", renderInline("see ‘https://a.test/y’", passLink), 'see ‘<a href="https://a.test/y" rel="noopener noreferrer">https://a.test/y</a>’');
throws("malformed escape is a link error", () => resolve("bad%E0.md"), 'link target "bad%E0.md" is malformed');
eq("query on a relative link is kept", resolve("../../docs/provenance.md?plain=1").href, "https://github.com/o/r/blob/main/docs/provenance.md?plain=1");

Expand Down
6 changes: 4 additions & 2 deletions site/lib/markdown.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,10 @@ export function renderInline(text, resolveLink) {
s = s.replace(/<(https?:\/\/[^\s<>]+)>/g, (_, url) => keep(`<a href="${esc(url)}" rel="noopener noreferrer">${esc(url)}</a>`));
// Bare URLs, leaving trailing sentence punctuation outside the link. A URL
// stops at `*` (bold around it) and at a slot (a code span right after it),
// and keeps a closing paren that balances one inside it (Foo_(bar)).
s = s.replace(/https?:\/\/[^\s<>"*\u0000]+/g, (url) => {
// and keeps a closing paren that balances one inside it (Foo_(bar)). Curly
// quotes end it too, as they do in the link check: quoted licence text wraps
// a URL in them (#274, #285).
s = s.replace(/https?:\/\/[^\s<>"*‘’“”\u0000]+/g, (url) => {
let [, core, tail] = url.match(/^(.*?)([.,;:!?)\]]*)$/);
while (tail.startsWith(")") && count(core, "(") > count(core, ")")) {
core += ")";
Expand Down
Loading