Discourse on regular expressions ahead. If you don't care for such a thing, just know that this is fixed in the next build.
Ah yes, the neverending story of link-within-a-link creation. We have several unpretty hacks in place to prevent this in multiple areas. Could just add another one for this new case.
There's a few ways of fixing it, but all this escaping and encoding problem characters is getting a bit messy, so I'm not sure what the best approach is.
So true, Tim.
It looks fine in the edit preview, though.
Hmm, you're right, nhahtdh. Now why would that be?
The reason for this is what is usually a deficiency in JavaScript regular expressions: They don't support lookbehinds.
I say "usually", because in this case, this gave me the idea for a fix that's much cleaner than doing yet another "encoding problem characters" step.
So the change to allow auto-linking of URLs preceded by a non-word character and neither by ="
nor by <
(which, despite all the havoc I've created with it so far, I still consider a good change), was implemented differently in the server-side Markdown version and in the client-side version. .NET regexes do support lookbehinds, so on the server it was as simple as
(?<!<|=")
For the JavaScript version, I had to simulate a negative lookbehind by using
(<|=")?
and by not handling a match if this group was matched.
Simulating lookbehinds this way has a disadvantage: The match also consumes these preceding characters; it's not a zero-width assertion. That's not a problem in this case though.
There's a second difference though. Imagine the following:
<a href="http://foo.com/http://bar.com">
^ ^ ^ ^
A B C D
When walking through this string, the server-side version doesn't match at B, because of the lookbehind. It continues on through the string, and finds a match at C, which is not preceded by ="
, and auto-links the part between C and D. Not what we like.
The JavaScript version on the other hand matches the full thing from A to D. It leaves it unchanged, because the (<|=")?
group was matched, but the important thing is: This match consumes the whole part from A to D. And thus the inner link from C to D is never touched.
From the next build on, the server-side version does the same thing as the client-side version. And I would never have believed I'd one day say "I'm glad that JavaScript regular expressions don't support lookbehinds".
;-)
)