9

I've been playing with a script that takes the selected text in Chrome and looks it up in Google, offering the four top choices, and then pasting the relevant link. It is pasted in different formats depending on which page is currently open in Chrome - DokuWiki format with DokuWiki open, HTML with normal websites, and I want rich text for my WordPress WYSIWYG editor.

I tried to use pbpaste -Prefer rtf to see what a rich-text link with no other styling looked like on the pasteboard, but it still outputs plain text. After saving a file in Text Edit, and experimenting, I came up with the following

text = %q|{\rtf1{\field{\*\fldinst{HYPERLINK "URL"}}{\fldrslt TEXT}}}|
text.gsub!("URL", url)
text.gsub!("TEXT", stext)

(I had to use the gsub, because somehow when using %Q and #{} to insert the variables, the string didn't work)

This works, however, when I paste it, there is an additional lineshift before and after the link. What would the string look like to avoid this?

Arjan
  • 22,808
  • 11
  • 61
  • 71
Stian Håklev
  • 1,240
  • 2
  • 14
  • 26

3 Answers3

16

From the shell the clean solution is this:

URL="http://www.google.com/"
NAME="Click here for Google"
echo "<a href='$URL'>$NAME</a>" | textutil -stdin -format html -convert rtf -stdout | pbcopy

So, use the textutil command to convert correct html .. into rtf...

ruby variant:

url = 'http://www.google.com'
name = 'click here'
system("echo '<a href=\"#{url}\">#{name}</a>' | textutil -stdin -format html -convert rtf -stdout | pbcopy")

so, when you run the above without pbcopy part, you'll get:

{\rtf1\ansi\ansicpg1250\cocoartf1038\cocoasubrtf350
{\fonttbl\f0\froman\fcharset0 Times-Roman;}
{\colortbl;\red255\green255\blue255;\red0\green0\blue238;}
\deftab720
\pard\pardeftab720\ql\qnatural
{\field{\*\fldinst{HYPERLINK "http://www.google.com/"}}{\fldrslt 
\f0\fs24 \cf2 \ul \ulc2 click here}}}

EDIT: Just tested this on BigSur and working as should. Any HTML is got converted to rtf. Another demo (without variables)

echo '<b>BOLD TEXT</b><br><a href="http://www.stackoverflow.com">stackoverflow link</a><br><h1>big title</h1>' | textutil -stdin -format html -convert rtf -stdout | pbcopy

after pasting into TextEdit yields

enter image description here

clt60
  • 62,119
  • 17
  • 107
  • 194
  • This is neat, but the problem persists - this solution also inserts a lineshift before and after the text to be copied. – Stian Håklev May 25 '11 at 13:32
  • 1
    Great solution. However, note that `-Prefer rtf` doesn't actually do anything here - it is meant for use with `pbpaste`, not `pbcopy`. `pbcopy` actually decides based on the *input data* what format to copy (either plain text, RTF, or EPS). – mklement0 May 15 '13 at 13:31
  • 1
    Thanks this works for me (shell script variant) although with a caveat. If I copy a link normally (say, by selecting text in a web browser and copying that), I can paste the link into applications that support rich text, but I can also paste a plain-text variant into applications that don't support rich text—i.e. the pasteboard contains both a rich text and a plain text variant. With this textutil / pbcopy method, there is *only* a rich text variant, so pasting into a plain-text application doesn't work. – jbyler Apr 06 '18 at 23:08
  • When I copy from, e.g., Telegram, I can paste rich text in Chrome. But copying the link the way described here, does not let me paste it in Chrome (though pasting in TextEdit works). Any ideas what is missing? – HappyFace Aug 26 '21 at 16:13
  • @jbyler Look at this [script](https://github.com/chbrown/macos-pasteboard/issues/8#issuecomment-906537204) to copy both rich text and plain text. – HappyFace Aug 26 '21 at 16:14
  • 1
    Does this still work for you on macOS Big Sur? It will paste an empty string here. – aaronk6 Sep 30 '21 at 15:23
  • 1
    Thanks! I was able to modify this to [copy CSVs as rich text tables](https://github.com/bbkane/dotfiles/blob/master/bin_common/bin_common/copy_as_rtf.py) suitable for pasting into spreadsheets/GDocs, etc. – Ben May 16 '22 at 02:47
  • This is resulting in an empty paste with BigSur. Anyone know of a currently working solution? – Sanjiv Jivan Jun 11 '22 at 18:21
  • @SanjivJivan sorry, can't test it / haven't access to BigSur... – clt60 Jun 12 '22 at 00:05
  • @jm666 this is the solution that did work https://assortedarray.com/posts/copy-rich-text-cmd-mac/ – Sanjiv Jivan Jun 12 '22 at 00:30
  • @SanjivJivan Just tested on BigSur. Working as should. Pasting into textedit got the link. – clt60 Jun 12 '22 at 06:45
  • @jm66 do you have Slack? This clipboard doesn't paste there using your approach (blank paste) while the rich clipboard using the link I provided works in any app. – Sanjiv Jivan Jun 12 '22 at 23:54
  • @SanjivJivan See, added second example and just tested both on BigSur. My answer is working (as it converts HTML to RTF) exactly as the OP asked in the question. so the the result shoud be in form `{\rtf1\....` and so on, as he asked. Maybe you want something different, so create another question and/or use any solution you like. Just be aware that rich text string and rich text clipboard are completely two different things. – clt60 Jun 14 '22 at 06:13
4

One way of doing this is using MacRuby, which is able to directly access the pasteboard through the Cocoa framework, rather than using the command line tool, which gives you more options.

For example, you can use this function to paste in HTML code, including hyperlinks, which will function correctly inserted into TextEdit or a WordPress editing box:

framework 'Cocoa'

def pbcopy(string)
  pasteBoard = NSPasteboard.generalPasteboard
  pasteBoard.declareTypes([NSHTMLPboardType], owner: nil)
  pasteBoard.setString(string, forType: NSHTMLPboardType)
end

This works much better than the command-line pbcopy, in that it definitively avoids adding white-space, and also avoids having to send RTF for rich text, where HTML is much easier to generate programmatically.

Stian Håklev
  • 1,240
  • 2
  • 14
  • 26
2

macOS's pbcopy command can detect RTF. The following example (using pandoc to convert markdown to RTF), places a rich text snippet in your paste buffer:

echo '**foo**' | pandoc -t rtf -s | pbcopy
mb21
  • 34,845
  • 8
  • 116
  • 142