Apple Script : How can I copy html content to the clipboard?
Asked Answered
M

6

15

I know how to copy plain text to the clipboard:

oascript -e 'set the clipboard to "plain text"'

But the question is how can I copy html contents to the clipboard? For example, how can I copy the following html content to the clipboard:

<b>bold text</b>

so that I get bold text when I paste it in TextEdit?

Thanks for the help in advance!


I found an intermediate solution for this:

echo "<b>bold text</b>" | textutil -stdin -stdout -format html -convert rtf | pbcopy

This works, so far so good, but unfortunately I found that it doesn't work for an image tag:

echo "<img src=\"https://www.google.com/images/srpr/logo3w.png\">" | textutil -stdin -stdout -format html -convert rtf | pbcopy

This does not do the job I want, so anybody knows the reason?
Thanks!


I've found a working solution and posted it below :)

Moderation answered 18/6, 2012 at 15:6 Comment(4)
The reason the img tag doesn't work is because RTF documents can probably only use embedded images, and therefore can't display images hosted on HTTP servers.Arte
I see. But the clipboard can seem to hold html contents definitely. When I drag and copy some image in Safari, and then dump the contents using the 'osascript -e "the clipboard"' command, it shows the data like '«data HTML3C6D65...binary data...»', and I believe there should a way to do the same job on the command line. ;)Moderation
I believe that since Safari has already downloaded the image, it copies the image itself when you put it on the clipboard. However, when you use the commands above, you're converting an incompatible img tag to RTF format, which leaves you with a broken image.Arte
It seems that RTF format can't contain images (downloaded nor referenced), so that's why my code failed. (and the Safari copies html code, not binary images.) But I could achieve the goal using raw html class directly without going through RTF class. Thanks for the help, Michael!Moderation
M
34

I've found a solution and the idea is to use the HTML class directly instead of the RTF class. (TextEdit or web editors can handle this HTML class as well as the RTF class data)
All you have to do is to convert your html code into raw hexcode.
The complete code looks like:

hex=`echo -n "your html code here" | hexdump -ve '1/1 "%.2x"'`
osascript -e "set the clipboard to «data HTML${hex}»"

You can combine them into one sentence, of course.
Hope this helped anybody interested. :)

Moderation answered 18/6, 2012 at 18:55 Comment(3)
Great solution; note that for UTF-8 support you should prefix your HTML snippets with <meta charset="utf-8">.Boudreaux
This works when I paste in, e.g., TextEdit, but I can't paste into a lot of other places, such as the web app of Discord. Any ideas?Hartzog
@Hartzog The target application has to support HTML. Discord however, expects plain text. As there can be multiple data types in the clipboard, we can fix this by adding a plain text representation to the clipboard without losing the HTML version: set the clipboard to {«class HTML»:«data HTML${hex}», string:"${plain}"}. I encountered this issue with Slack, which is actually capable of handling HTML, but still refuses to do so if there is no plain text available. Details: aaron.cc/…Cyanide
W
6

The solution by @k-j would not work if the input HTML is too big, you might encounter some error messages like below:

/usr/bin/osascript: Argument list too long

I made some improvements to @k-j's solution by converting it to an executable and handling data via pipe. I hope it helps as well.

Executable

~/bin/pbcopyhtml:

#!/bin/sh
printf "set the clipboard to «data HTML$(cat $@ | hexdump -ve '1/1 "%.2x"')»" | osascript -

Usage

from pipe

$ printf '# title\n\n- list\n- list' | cmark | ~/bin/pbcopyhtml
$ osascript -e 'the clipboard as record'
«class HTML»:«data HTML3C68313E7469746C653C2F68313E0A3C756C3E0A3C6C693E6C6973743C2F6C693E0A3C6C693E6C6973743C2F6C693E0A3C2F756C3E0A»

from file

$ printf '# title\n\n- list\n- list' | cmark > sample.html
$ ~/bin/pbcopyhtml sample.html
$ osascript -e 'the clipboard as record'
«class HTML»:«data HTML3C68313E7469746C653C2F68313E0A3C756C3E0A3C6C693E6C6973743C2F6C693E0A3C6C693E6C6973743C2F6C693E0A3C2F756C3E0A»
Wiggs answered 20/3, 2020 at 4:18 Comment(1)
The syntax required is insane, but this pbcopyhtml script works very well, thank you! (Makes Linux+X11 syntax of xclip -sel clipboard -o -t text/html look extremely straightforward and logical in comparison 😬)Pebrook
P
3

I wasn't able to use any other solution in this thread on Yosemite. When putting RTF content into the clipboard things worked when pasting into TextEdit, but not when pasting into Chrome (I wanted to script pasting into a Google Sheets spreadsheet). Eventually I was able to get this to work:

set rawHTML to "<a href=\"" & gmailURL & "\">" & myTitle & "</a>"
set escapedData to do shell script "echo " & (quoted form of rawHTML) as «class HTML»
set the clipboard to escapedData
Pulverize answered 31/12, 2015 at 18:50 Comment(0)
A
1

I'm not super great at AppleScript, but here's something that works. Unfortunately, since it opens a Safari window, it's not instant. You may need to adjust the delay value to compensate for slower performance, but 0.25 s seemed long enough in my tests.

set theHTML to "<b>bold text</b>"

tell application "Safari"
    open location "data:text/html," & theHTML
    activate
    tell application "System Events"
        keystroke "a" using {command down}
        keystroke "c" using {command down}
    end tell
    delay 0.25
    close the first window
end tell

After that, the rendered text should be on your clipboard, ready to paste into TextEdit.

Arte answered 18/6, 2012 at 15:39 Comment(1)
Thanks for the answer, Michael! Your answer could be a good workaround, I think there should be a simpler way to do this without using Safari. But I appreciate and +1 for the answer!Moderation
K
0

Sorry, but your code won't even compile in AppleScript Editor in OS X Mavericks

hex=`echo -n "your html code here" | hexdump -ve '1/1 "%.2x"'`
osascript -e "set the clipboard to «data HTML${hex}»"

However, I have found the following code does work well:

set the_HTML to "<font size=4 face=\"verdana\"><a href=\"" & the_url & "\" target=_blank>" & link_text & "</a></font>"
--set the clipboard to the_text

do shell script "echo " & quoted form of the_HTML & " | textutil -format html -convert rtf -stdin -stdout | pbcopy -Prefer rtf"

Of course you will need to set the AppleScript variables "the_url" and "link_text" prior to the above statements.

Koralle answered 26/4, 2015 at 5:56 Comment(1)
Doesn't seem to work anymore.Doge
E
0

(Expanding on the anwser by Ryan Pattersson that works like a charm.)

You can create a subroutine that puts a link to the clipboard and then call it from multiple places in your code

my urlToClipboard("Gmail", "http://gmail.com")

on urlToClipboard(theTitle, theUrl)
    set rawHTML to "<a href=\"" & theUrl & "\">" & theTitle & "</a>"
    set escapedData to do shell script "echo " & (quoted form of rawHTML) as «class HTML»
    set the clipboard to escapedData
end urlToClipboard
Exhume answered 3/7, 2016 at 9:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.