Copy-as-Markdown and Paste-as-Markdown for macOS with Hammerspoon and Pandoc
TLDR:
hs -c "hs.pasteboard.readStyledText():convert('html')" | pandoc -f html -t gfm-raw_html+hard_line_breaks
Or bind it to a keyboard shortcut like ⌘-⌥-C
to achieve “copy-as-Markdown” like the following:
hs.hotkey.bind({ 'cmd', 'alt' }, 'c', function()
-- Sometimes a single cmd+c has no effect
hs.eventtap.keyStroke({ 'cmd' }, 'c')
hs.eventtap.keyStroke({ 'cmd' }, 'c')
local task = hs.task.new(
os.getenv('HOME') .. '/.nix-profile/bin/pandoc',
--[[callbackFn=]] function(task, stdOut, stdErr)
hs.pasteboard.setContents(stdOut)
hs.alert('Copied as Markdown')
end,
--[[arguments=]] { '-f', 'html', '-t', 'gfm-raw_html+hard_line_breaks' }
)
task:setInput(hs.pasteboard.readStyledText():convert('html'))
task:start()
end)
Similarly, this can achieve “paste-as-Markdown”:
hs.hotkey.bind({ 'cmd', 'alt' }, 'v', function()
local task = hs.task.new(
os.getenv('HOME') .. '/.nix-profile/bin/pandoc',
--[[callbackFn=]] function(task, stdOut, stdErr)
hs.eventtap.keyStrokes(stdOut)
end,
--[[arguments=]] { '-f', 'html', '-t', 'gfm-raw_html+hard_line_breaks' }
)
task:setInput(hs.pasteboard.readStyledText():convert('html'))
task:start()
end)
You might need to change the path to pandoc
depending on how its installed.
This requires:
- Hammerspoon (the
hs
CLI needs IPC installed) for reading RTF clipboard content and exporting it as HTML - Pandoc for converting HTML to Markdown
TODO:
- Copying with
hs.eventtap.keyStroke({ 'cmd' }, 'c')
doesn’t work in Notes.app for some reasons - Pasting with
hs.eventtap.keyStrokes(stdOut)
is a bit slower than ideal, an alternative is tohs.pasteboard.setContents(stdOut)
thenhs.eventtap.keyStroke({ 'cmd' }, 'v')
, but that only works if you are pasting once
Notes
Note on the gfm-raw_html
part: :convert('html')
produces HTML like the following:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta http-equiv="Content-Style-Type" content="text/css">
<title></title>
<meta name="Generator" content="Cocoa HTML Writer">
<meta name="CocoaVersion" content="2299.74">
<style type="text/css">
p.p1 {margin: 0.0px 0.0px 12.0px 0.0px; font: 12.0px Times; -webkit-text-stroke: #000000}
span.s1 {font-kerning: none}
span.s2 {text-decoration: underline ; font-kerning: none; color: #0000e9; -webkit-text-stroke: 0px #0000e9}
span.s3 {font: 13.0px Courier; text-decoration: underline ; font-kerning: none; color: #0000e9; -webkit-text-stroke: 0px #0000e9}
</style>
</head>
<body>
<p class="p1"><span class="s1">Pandoc can convert between numerous markup and word processing formats, including, but not limited to, various flavors of <a href="https://daringfireball.net/projects/markdown/"><span class="s2">Markdown</span></a>, <a href="https://www.w3.org/html/"><span class="s2">HTML</span></a>, <a href="https://www.latex-project.org/"><span class="s2">LaTeX</span></a> and <a href="https://en.wikipedia.org/wiki/Office_Open_XML"><span class="s2">Word docx</span></a>. For the full lists of input and output formats, see the <a href="https://pandoc.org/MANUAL.html#option--from"><span class="s3">--from</span></a> and <a href="https://pandoc.org/MANUAL.html#option--to"><span class="s3">--to</span></a> <a href="https://pandoc.org/MANUAL.html#general-options"><span class="s2">options below</span></a>. Pandoc can also produce <a href="https://www.adobe.com/pdf/"><span class="s2">PDF</span></a> output: see <a href="https://pandoc.org/MANUAL.html#creating-a-pdf"><span class="s2">creating a PDF</span></a>, below.</span></p>
</body>
</html>
If you just convert it to markdown
or gfm
, you’ll get:
[Pandoc can convert between numerous markup and word processing formats,
including, but not limited to, various flavors of
[[Markdown]{.s2}](https://daringfireball.net/projects/markdown/),
[[HTML]{.s2}](https://www.w3.org/html/),
[[LaTeX]{.s2}](https://www.latex-project.org/) and [[Word
docx]{.s2}](https://en.wikipedia.org/wiki/Office_Open_XML). For the full
lists of input and output formats, see the
[[\--from]{.s3}](https://pandoc.org/MANUAL.html#option--from) and
[[\--to]{.s3}](https://pandoc.org/MANUAL.html#option--to) [[options
below]{.s2}](https://pandoc.org/MANUAL.html#general-options). Pandoc can
also produce [[PDF]{.s2}](https://www.adobe.com/pdf/) output: see
[[creating a PDF]{.s2}](https://pandoc.org/MANUAL.html#creating-a-pdf),
below.]{.s1}
Note the s1
, s2
tags.
Using gfm-raw_html
as per https://stackoverflow.com/a/62963659 strips those tags.
Pandoc can convert between numerous markup and word processing formats,
including, but not limited to, various flavors of
[Markdown](https://daringfireball.net/projects/markdown/),
[HTML](https://www.w3.org/html/),
[LaTeX](https://www.latex-project.org/) and [Word
docx](https://en.wikipedia.org/wiki/Office_Open_XML). For the full lists
of input and output formats, see the
[--from](https://pandoc.org/MANUAL.html#option--from) and
[--to](https://pandoc.org/MANUAL.html#option--to) [options
below](https://pandoc.org/MANUAL.html#general-options). Pandoc can also
produce [PDF](https://www.adobe.com/pdf/) output: see [creating a
PDF](https://pandoc.org/MANUAL.html#creating-a-pdf), below.