diff --git a/CLAUDE.md b/CLAUDE.md
index 2366241..da93618 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -153,7 +153,10 @@ Things worth knowing before editing:
a key in that same comment's own `media_metadata`, so `resolveInlineImages` is one
lookup rather than three special cases. A bare `preview.redd.it` address pasted into a
comment is in there too, keyed by the id inside the URL. Prefer `s.gif` over `s.mp4`
- for an animated one: a GIF moves in an `` and an MP4 needs a player.
+ for an animated one: a GIF moves in an `
` and an MP4 needs a player. An address
+ typed without a scheme counts as well, but only when it ends in an image extension —
+ the rule wants a host, a path *and* that extension, because comments are full of
+ dotted, slashed prose that must not turn into links.
- **Threads** — same media schema as Instagram (`src/platforms/meta-media.ts`). Its
payloads are full of empty stub nodes, so the finder only accepts a node with actual
candidates in it. The page ships the linked post, the author's follow-ups, other
diff --git a/src/render/markdown.ts b/src/render/markdown.ts
index 4f519e4..cd1c0c4 100644
--- a/src/render/markdown.ts
+++ b/src/render/markdown.ts
@@ -69,7 +69,12 @@ const INLINE = new RegExp(
'(?]+)', // 10 bare url
- '(?]*\\.(?:jpe?g|png|gif|webp|avif)(?:\\?[^\\s<>]*)?)',
+ '(?
test('images inside a quote are still placed', () => {
assert.match(mdi('> '), /
{ + // Which is how people type them: no https, straight from the address bar. + const out = mdi('preview.redd.it/lz4drsqh0clh1.jpeg?width=1290&s=b27e'); + assert.ok(out.includes('
{ + const out = mdi('look at i.redd.it/x.png nice one'); + assert.ok(out.startsWith('
look at
'), out); +}); + +test('prose full of dots and slashes is not mistaken for an address', () => { + // The reason this rule insists on a host, a path and an image extension. + for (const text of [ + 'the file is at src/render/post.ts', + 'see node_modules/foo/bar.js', + 'a path like ./images/cat.jpg', + 'C:/Users/x/cat.png', + 'email someone@example.com/nope.jpg', + 'version 1.2.3/4.png', + ]) { + assert.ok(!mdi(text).includes('
{ + // Guessing a scheme is worth it for a picture and not for prose. + assert.equal(mdi('example.com/article'), '
example.com/article
'); +});