I have an Automator Service that takes the current text on the clipboard and writes it to a new .txt file. This is executed simply with the following piece of AppleScript code:
do shell script "pbpaste > /path/to/your/clipboard-file.txt"
This code is from the following Stack Overflow answer:
AppleScript to paste text from clipboard into a file
However, this code converts the clipboard contents to plain text, removing all of the text's formatting.
Is it possible to use AppleScript to write the clipboard contents to an .rtf or .rtfd file, while preserving the original formatting of the clipboard contents? By original formatting, I am referring to stylistic data such as typographical emphasis (bold, italics, underline), font size, and text color.
On a whim, I tried the following command:
do shell script "pbpaste > /path/to/your/clipboard-file.rtf"
But this command resulted in an .rtf file that my computer was unable to read or open.
Best Answer
This answer has been updated to reflect rubik's sphere's misunderstanding between what Rich Text is (what was originally asked about) and what's actually being worked with from Google Chrome, being HTML. (See comments moved to chat.)
I'm leaving the original answer as is, and below this new content, as it does technically answer the original question as asked. It also contains relevant information to the overall process of dealing with Clipboard content in the context of the original and modified question.
The code below is example code to be tested and run within (Apple) Script Editor, as aside from the first sentence in the question, no explicit and specific usage within Automator has, yet, been given. The code may need to be edited to work within the unknown usage in Automator. That said, as written, if the entire script below was placed by itself into a Run AppleScript action, by itself, in Automator... it works as is. If using only segments of the code, some changes to the existing code could need to be made.
The code below contains sufficient commenting so as to understand overall what the script is doing.
Original answer to the original question asked:
To get Rich Text content from the Clipboard into a file using AppleScript, it's a bit more complex then a simple
do shell script
command.The example AppleScript code below will, if the target file doesn't already exist and if Rich Text content exists on the Clipboard, write it to a file. It will have all the attributes as the RichText content on the Clipboard has, as it did when copied to the Clipboard.
Open Script Editor and copy and paste the code below into a new Untitled document and then run it from Script Editor, reviewing the output in Events/Replies. Run it a couple of times, with and without Rich Text content on the Clipboard and with and without the existence of the file, on the hard drive, defined by
set theRichTextFileName ...
at the start of the script.You'll see the code makes sure the file doesn't exist, so as not to overwrite an exiting file of the target name and location and if the Clipboard doesn't contain Rich Text content, it displays a message for that too.
Now if using this in an Automator Service e.g., where Service receives selected rich text, then the code can be modified not to trap for an error if Rich Text content isn't on the Clipboard as the service will not appear on the Services menu if Rich Text is not selected in a document. Also if you want to overwrite the target file at its designated location the code around that can be removed too. I'll give those code examples as well.
Example code to paste into Script Editor for testing and review:
Example code to use in an Automator Service e.g., where Service receives selected rich text:
Example code to use in an Automator Service e.g., where Service receives selected rich text and overwrites existing target file:
The image below is of an example Automator Service that creates the New RichText Filename.rtf file from selected Rich Text from the Create Rich Text file from Clipboard service on the Services Context menu (by right-click) or Application_name > Services > menu, when Rich Text is selected in a document.
Now these are just examples and additional logic can be coded to tailor it to meet ones needs. As an example, code could be added to automatically increment an existing file's name so as not to overwrite it, or prompt for a new file name and complete the operation vs. aborting with a message that the file already exists, etc.
Update for use with a
do shell script
command:If you really want to do it using a
do shell script
command, then use the following code while replacing/path/to/new rich text file.rtf
with a valid path filename to a location you have write permissions. Note not to remove the\"
before and after/path/to/new rich text file.rtf
in the actual command as this handles the path filename if containing spaces. If the path filename does not contain spaces, then the\"
before and after/path/to/new rich text file.rtf
does not need to be used.Here's the command line showing as wrapped text, for easier viewing:
do shell script "osascript -e 'try' -e 'get the clipboard as «class RTF »' -e 'end try' | awk '{print substr($0, 12, length($0)-13)}' | xxd -r -p > \"/path/to/new rich text file.rtf\""
While one can copy and paste (recommend) the code, nonetheless here's how to type the Double Angle Quotation Marks, which are also available under Parentheses in (Special) Characters, e.g. optioncommandT in TextEdit.
Note: Keep in mind the spacing in
«class RTF »
is meant to be offset in this use case.Typing Double Angle Quotation Marks
Note that, as written, this
do shell script
command overwrites the output file if it already exists, without prompting! It will either be a zero length file if the Clipboard does not contain any Rich Text content, otherwise the file will be of necessary length to contain the Rich Text content from the Clipboard. Obviously, additional logic could be coded into theosascript
command however if you need more complexity then this you're better off using the method first presented in this answer. Or using an external script being called bydo shell script
command that handles all the necessary logic and error handling based on the complexity of the overall conditions this will be applied under.do shell script "pbpaste > /path/to/clipboard-file.rtf"
?That's a good question and while
pbpaste
does have the-Prefer {txt | rtf | ps}
option, nonethelesspbpaste -Prefer rtf
may not output Rich Text even if it exists on the Clipboard. Or what it does output, if not ASCII Text, will not be a form of Rich Text that is understood, by e.g TextEdit, and or will not contain all the Rich Text attributes if any, that the Clipboard content contains.This makes it necessary to get the Rich Text content on Clipboard in a different manner and why
get the clipboard as «class RTF »
is being used instead. When using ado shell script
command with this, it requires additional processing to utilize the data returned, as it's in a data wrapper when returned and not immediately usable, thus requires further processing.As an example,
Hello World!
in Rich Text on the Clipboard can look like this in ASCII Text:The above format unfortunately is not easily usable, if at all, in AppleScript and I believe that's why being grabbed as Hex encoded data is required.
get clipboard info
command for the Clipboard content in this example returns{«class RTF », 265}
among the info returned, nonetheless while the ASCII Text form of this Rich Text content is 265 bytes long it is returned in Hex format at over twice the bytes with the data wrapper. The fact that it's returned in Hex byget the clipboard as «class RTF »
in both the Script Editor or usingosascript
support this supposition.Here's the same
Hello World!
in Rich Text on the Clipboard in Hex:7B5C727466315C616E73695C616E7369637067313235325C636F636F61727466313138375C636F636F617375627274663430300A7B5C666F6E7474626C5C66305C666E696C5C66636861727365743020436F6D696353616E734D533B7D0A7B5C636F6C6F7274626C3B5C7265643235355C677265656E3235355C626C75653235353B7D0A5C706172645C74783732305C7478313434305C7478323136305C7478323838305C7478333630305C7478343332305C7478353034305C7478353736305C7478363438305C7478373230305C7478373932305C7478383634305C7061726469726E61747572616C0A0A5C66305C625C66733336205C6366302048656C6C6F20576F726C64217D
However, what's returned by
get the clipboard as «class RTF »
for theHello World!
example above is:«data RTF 7B5C727466315C616E73695C616E7369637067313235325C636F636F61727466313138375C636F636F617375627274663430300A7B5C666F6E7474626C5C66305C666E696C5C66636861727365743020436F6D696353616E734D533B7D0A7B5C636F6C6F7274626C3B5C7265643235355C677265656E3235355C626C75653235353B7D0A5C706172645C74783732305C7478313434305C7478323136305C7478323838305C7478333630305C7478343332305C7478353034305C7478353736305C7478363438305C7478373230305C7478373932305C7478383634305C7061726469726E61747572616C0A0A5C66305C625C66733336205C6366302048656C6C6F20576F726C64217D»
The Hex encoded string is in a
«data RTF »
wrapper which needs to be removed before converting the Hex encoded content to ASCII Text to be written to a disk file by the use of I/O Redirection, e.g.>
, in thedo shell script
command example above.So, the output of
osascript -e 'try' -e ' get the clipboard as «class RTF »' -e 'end try'
gets piped (|
) toawk
where it creates a substring, printing only the Hex encoded content itself, not the data wrapper portion, as that would not be processed properly byxxd
in the next step of the process.It then has to be piped (
|
) toxxd
for conversion toASCII Text
to be written to a disk file using I/O Redirection, e.g.>
, to the target path filename.The image below is of Clipboard Viewer toggling between ASCII Text and Hex encoding views, showing
Hello World!
copied from a Rich Text Document, the one used in this example.I hope this provides a better understanding of how AppleScript works with Rich Text content on the Clipboard, as either way conversion from a Hex encoded string to ASCII Text has to take place and this is being done transparently in the original example code while requiring additional processing outside of AppleScript code being processed by
osascript
when using thedo shell script
command in this context.