What happens
When a clipboard carries a URL as text/plain and an anchor labelled with a shortened rendering of that URL as text/html, pasting into a GitHub comment box inserts the Markdown link syntax inside the URL:
text/plain: https://github.com/owner/repo/blob/main/a.js#L7
text/html: <a href="https://github.com/owner/repo/blob/main/a.js#L7">repo/blob/main/a.js#L7</a>
pasted: https://github.com/owner/[repo/blob/main/a.js#L7](https://github.com/owner/repo/blob/main/a.js#L7)
expected: [repo/blob/main/a.js#L7](https://github.com/owner/repo/blob/main/a.js#L7)
It renders as two links, one of them junk (https://github.com/owner/ on its own), and the comment has to be repaired by hand.
Reproduction
Run this in the console of any page with a GitHub comment box, press ⌘C/Ctrl+C, then paste into the box:
document.addEventListener('copy', event => {
const url = 'https://github.com/owner/repo/blob/main/a.js#L7'
event.clipboardData.setData('text/plain', url)
event.clipboardData.setData('text/html', `<a href="${url}">repo/blob/main/a.js#L7</a>`)
event.preventDefault()
}, {once: true})
Why it happens
convertToMarkdown starts from the plaintext flavour and splices [label](href) over the label at the offset where indexOf finds it:
https://github.com/github/paste-markdown/blob/main/src/paste-markdown-html.ts#L83-L90
That is correct for prose containing a link, where the plaintext is a flattening of the HTML. Here the plaintext is the URL and the label is a substring of it, so the label is found at offset 25 rather than 0 and the splice covers only the tail.
The same corruption happens when prose wraps the URL in punctuation — plaintext (https://github.com/owner/repo/blob/main/a.js#L7) yields (https://github.com/owner/[repo/…#L7](…)).
Who hits it
Any tool that writes a link to the clipboard as "URL as plaintext, shortened label as HTML" — macOS automation scripts (Hammerspoon/Alfred/Keyboard Maestro), clipboard managers, and "copy link" affordances that shorten the visible text. Labels containing a character the URL does not (repo#1234) are unaffected, because indexOf misses and the paste is left alone; every label that is a substring of its own URL is affected.
Proposed fix
#117 — replaces the whole URL when the label is a shortened rendering of it, declines rather than corrupting when the label sits inside a URL that is not its own href, and leaves every other case on the existing path. Four regression tests, all failing before the change.
What happens
When a clipboard carries a URL as
text/plainand an anchor labelled with a shortened rendering of that URL astext/html, pasting into a GitHub comment box inserts the Markdown link syntax inside the URL:It renders as two links, one of them junk (
https://github.com/owner/on its own), and the comment has to be repaired by hand.Reproduction
Run this in the console of any page with a GitHub comment box, press ⌘C/Ctrl+C, then paste into the box:
Why it happens
convertToMarkdownstarts from the plaintext flavour and splices[label](href)over the label at the offset whereindexOffinds it:https://github.com/github/paste-markdown/blob/main/src/paste-markdown-html.ts#L83-L90
That is correct for prose containing a link, where the plaintext is a flattening of the HTML. Here the plaintext is the URL and the label is a substring of it, so the label is found at offset 25 rather than 0 and the splice covers only the tail.
The same corruption happens when prose wraps the URL in punctuation — plaintext
(https://github.com/owner/repo/blob/main/a.js#L7)yields(https://github.com/owner/[repo/…#L7](…)).Who hits it
Any tool that writes a link to the clipboard as "URL as plaintext, shortened label as HTML" — macOS automation scripts (Hammerspoon/Alfred/Keyboard Maestro), clipboard managers, and "copy link" affordances that shorten the visible text. Labels containing a character the URL does not (
repo#1234) are unaffected, becauseindexOfmisses and the paste is left alone; every label that is a substring of its own URL is affected.Proposed fix
#117 — replaces the whole URL when the label is a shortened rendering of it, declines rather than corrupting when the label sits inside a URL that is not its own href, and leaves every other case on the existing path. Four regression tests, all failing before the change.