NSPasteboard, Array/Types

Every application get/set specific types for pasteboard.

ex.

Safari set the first types of copy selected text to webarchive. Apple Mail support webarchive
as paste object. When we copy data and paste it to other application it could be we want
something else. The first script could answer the question what kind of types are supported
for the target application. The second script setData forType so the choosen type become the
first and only type.

The first Script make a array/list of supported types for pasteboard of specific application.

The interesting part about understanding NSPasteboard method and applications different types.
Some application could output to html. We could save this to a file. Open the html file in Safari
Make webarchive and send it to Apple mail. The reason it could be a working solution is the layout
of the data is much better. But not only that Apple mail also let us to edit the data before we
send it.

ex. It would be possible to send styled Excel data from Apple mail, that is interesting. (webarchive)

Other approach could be: Lets say you have got a email with a nice layout of html5 email.
And you like to use that code to build your template. You could select all in Apple mail of target
email and save it to file as html. To do that we will use pasteboard and type public.html.
Now we could edit the file and add/remove to be used as template for email.

use framework "Foundation"
use framework "AppKit"
use scripting additions

(**
* [Instance Property]: types
*	An array of the receiver’s supported data types.
**
* @property(nullable, readonly, copy) NSArray<NSPasteboardType> *types;
*)
set pasteboard to (current application's NSPasteboard's generalPasteboard())'s types() as list
return (choose from list pasteboard) as text

The second script set the pasteboard type to the first type.

use framework "Foundation"
use framework "AppKit"
use scripting additions

set pasteboardTypeList to {"url", "color", "contents", "file-url", "html", "text-selection", "pdf", "png", "rtf", "rtfd", "sound", "string", "tabular-text", "tiff", "webarchive"}

my setPasteboardType:((choose from list pasteboardTypeList) as text)

on setPasteboardType:_pasteboardType
	set pasteboard to current application's NSPasteboard's generalPasteboard()
	if (_pasteboardType is "url") then
		set theData to pasteboard's dataForType:(current application's NSPasteboardTypeURL)
		pasteboard's clearContents()
		pasteboard's setData:theData forType:(current application's NSPasteboardTypeURL)
	end if
        if (_pasteboardType is "color") then
		set theData to pasteboard's dataForType:(current application's NSPasteboardTypeColor)
		pasteboard's clearContents()
		pasteboard's setData:theData forType:(current application's NSPasteboardTypeColor)
	end if
	if (_pasteboardType is "contents") then
		set theData to pasteboard's dataForType:(current application's NSFileContentsPboadType)
		pasteboard's clearContents()
		pasteboard's setData:theData forType:(current application's NSFileContentsPboadType)
	end if
	if (_pasteboardType is "file-url") then
		set theData to pasteboard's dataForType:(current application's NSPasteboardTypeFileURL)
		pasteboard's clearContents()
		pasteboard's setData:theData forType:(current application's NSPasteboardTypeFileURL)
	end if
	if (_pasteboardType is "html") then
		set theData to pasteboard's dataForType:(current application's NSPasteboardTypeHTML)
		pasteboard's clearContents()
		pasteboard's setData:theData forType:(current application's NSPasteboardTypeHTML)
	end if
	if (_pasteboardType is "text-selection") then
		set theData to pasteboard's dataForType:(current application's NSPasteboardTypeMultipleTextSelection)
		pasteboard's clearContents()
		pasteboard's setData:theData forType:(current application's NSPasteboardTypeMultipleTextSelection)
	end if
	if (_pasteboardType is "pdf") then
		set theData to pasteboard's dataForType:(current application's NSPasteboardTypePDF)
		pasteboard's clearContents()
		pasteboard's setData:theData forType:(current application's NSPasteboardTypePDF)
	end if
	if (_pasteboardType is "png") then
		set theData to pasteboard's dataForType:(current application's NSPasteboardTypePNG)
		pasteboard's clearContents()
		pasteboard's setData:theData forType:(current application's NSPasteboardTypePNG)
	end if
	if (_pasteboardType is "rtf") then
		set theData to pasteboard's dataForType:(current application's NSPasteboardTypeRTF)
		pasteboard's clearContents()
		pasteboard's setData:theData forType:(current application's NSPasteboardTypeRTF)
	end if
	if (_pasteboardType is "rtfd") then
		set theData to pasteboard's dataForType:(current application's NSPasteboardTypeRTFD)
		pasteboard's clearContents()
		pasteboard's setData:theData forType:(current application's NSPasteboardTypeRTFD)
	end if
	if (_pasteboardType is "sound") then
		set theData to pasteboard's dataForType:(current application's NSPasteboardTypeSound)
		pasteboard's clearContents()
		pasteboard's setData:theData forType:(current application's NSPasteboardTypeSound)
	end if
	if (_pasteboardType is "string") then
		set theData to pasteboard's dataForType:(current application's NSPasteboardTypeString)
		pasteboard's clearContents()
		pasteboard's setData:theData forType:(current application's NSPasteboardTypeString)
	end if
	if (_pasteboardType is "tabular-text") then
		set theData to pasteboard's dataForType:(current application's NSPasteboardTypeTabularText)
		pasteboard's clearContents()
		pasteboard's setData:theData forType:(current application's NSPasteboardTypeTabularText)
	end if
	if (_pasteboardType is "tiff") then
		set theData to pasteboard's dataForType:(current application's NSPasteboardTypeTIFF)
		pasteboard's clearContents()
		pasteboard's setData:theData forType:(current application's NSPasteboardTypeTIFF)
	end if
	if (_pasteboardType is "webarchive") then
		set theData to pasteboard's dataForType:"com.apple.webarchive"
		pasteboard's clearContents()
		pasteboard's setData:theData forType:"com.apple.webarchive"
	end if
end setPasteboardType:

And its also possible to write the pasteboard data to a file, like in this example of copy
text on website with Safari to save it as webarchive. I know Shane did a similar thing with
WebView, here is my code https://macscripter.net/viewtopic.php?id=47908
Here is Shanes code: https://macscripter.net/viewtopic.php?pid=194944#p194944

That said, this approach for webarchive is very limited, better to use Shanes code.

This approach do not use WebView or WebKit framework

use framework "Foundation"
use framework "AppKit"
use scripting additions

set thePath to POSIX path of (path to desktop) & "somefile.webarchive"
set theURL to current application's |NSURL|'s fileURLWithPath:thePath

my pasteboardToURL:theURL dataForType:"com.apple.webarchive"

on pasteboardToURL:_theURL dataForType:_theDataForType
	set pasteboard to current application's NSPasteboard's generalPasteboard()
	set theData to pasteboard's dataForType:_theDataForType
	if theData = missing value then error "No data found on clipboard"
	set theResult to (theData's writeToURL:_theURL atomically:true)
	return theResult
end pasteboardToURL:dataForType:

I wonder if you’re misunderstanding, or I’m not following what you are saying. They types method returns the types available to be pasted, period. Perhaps the word receiver in the docs is confusing you: it means the receiver of the message sent by the method, which is the general pasteboard in this case.

And I’m a bit baffled by the second script. If the pasteboard can provide dataForType: , then setting it to that data seems pointless.

Also, some of those types — font, ruler, and find options — are stored on their own pasteboards, not the general pasteboard.

Hi Shane, I will do my best to explain the approach or thinking I had.
The code was meant to understand NSPasteboard, in same regard as clipboard info.
To understand the difference, and why something could be a approach we want or do not want.

  1. I need a way to figure out what kind of types are supported for target application.
  2. If I filter out or force the type to become the only type on pasteboard I could use command+v

To know the difference between rtf vs rtfd we could properly google to get that information.
But we could also make test case by forcing the type to be the only type on the pasteboard.
ex. rtf doesn’t include embedded image but rtfd does

If I have more 1 type on pasteboard if I use command+v it will give me what it think is the best.
That is not enough if we like to have something else. Or understand the difference between A vs B

I hope that make sense, at last I have learn more about NSPasteboard. :slight_smile:

ex.
If you select some text on Website and use command-c. We could see from the first script it doesn’t include rtfd type. The reason is no image was selected when we did the (command-c)
If you do the same thing but this time include text and image in your selection (command+c)
it will include rtfd type.

The script only give information about the pasteboard for a specific target application. In other
words if we copy image from Safari. The first choose is public.tiff or NeXT TIFF v4.0 pasteboard type
if we use command+v in TextEdit it will give a image. It perhaps is what we are looking when we
use copy image from Safari. It also tell us we could get something else from the pasteboard from
the action copy image.

ex.

set theImageTitle to pasteboard’s dataForType:“WebURLsWithTitlesPboardType”
set theImageData to pasteboard’s dataForType:(current application’s NSPasteboardTypeTIFF)

My approach to know what type to choose from I need to know the information to ask for.

Copy from Apple Reference Guide:
A type is frequently, but not necessarily, a UTI (Uniform Type Identifier)…
Apps can define their own types for custom data such as com.mycompany.myapp.mytype; however, in this case, only those apps that know of the type could understand the data written to the pasteboard.

ex. iWork has pasteboard types that maybe only make sense to iWork application.
If we do command+a and coomand+c on document in Pages that include styled text and image.
If we run the first script we could see it include iWork specific types and no rtfd type.
If we use command+v in TextEdit it ask us if we like to convert the document to rtfd.
So if I understand this correct when TextEdit receive the data from pasteboard it has to know
the type before it could ask the user to convert it. Could it be there is hidden functions or
relationship between applications. If TextEdit ask the user to convert to rtfd why doesn’t Apple
include rtfd type in Pages. The convert is a fake rtfd because what happen is TextEdit make a image
data of the document layout from Pages in other words PNG image. It means isn’t possible to
edit the text in TextEdit.

So would it be possible to copy text from Pages, yes and no… it all depend what we want…
Pages only provide plain-text and the styled text will be lost. And if we only send a mail copy its maybe okey as PNG or PDF of Pages document.

ex. command+a and command+c in Safari is: Select All and Copy.
If we us command+v in mail it will send webarchive type.

But we could also see there is rtfd format in the pasteboard and maybe we like to use that instead
to filter the css style from the paste option (command-v).

Let me go deeper how I think. If we use command+c and command+v on th keyboard for copy/paste
the pasteboard will provide what it think is the best approach.

ex. From Safari NSPasteboardTypeURL is not same as WebURLsWithTitlesPboardType
Both give a link but do it differently.

NSPasteboardTypeURL give a text with start with http… include the link…
WebURLsWithTitlesPboardType only give a text of the title there the link include http…
copy image address in Safari give a third option what text will return for the link.

if you copy image and paste it to TextEdit it will give image, but its also possible to get other
information from the pasteboard if remove what we do not want. Its like a (force pasteboard type)
when we use command+v on the keyboard.

If we use command+v we do not have any control what TextEditor will return. By removing the
types we do not want we force the type to become something else.

Shane does that make sense what I try to do ??

You are right… I read about it yesterday so it doesn’t make any sense to be there.

ex.

APPKIT_EXTERN NSString *NSGeneralPboard;
APPKIT_EXTERN NSString *NSFontPboard;
APPKIT_EXTERN NSString *NSRulerPboard;
APPKIT_EXTERN NSString *NSFindPboard;
APPKIT_EXTERN NSString *NSDragPboard;

No. The app you’re pasting into controls what it chooses, either by passing a list of types in preferred order, or checking if a type it prefers is available before asking for it specifically (or falling back to another choice).

Yes, but you can’t always remove types — certainly not like that. Consider this, using a section of your code:

set pb to current application's NSPasteboard's generalPasteboard()
-- put rich text on clipboard
pb's clearContents()
pb's writeObjects:{current application's NSAttributedString's alloc()'s initWithString:"blah"}
set y to pb's |types|()
set theData to pb's dataForType:(current application's NSPasteboardTypeRTF)
pb's clearContents()
pb's setData:theData forType:(current application's NSPasteboardTypeRTF)
set z to pb's |types|()
y's isEqualToArray:z --> true

You can generally only remove “richer” types of information.

Exactly, so if you copy image link in Safari, you will have public.tiff and you could paste to TextEdit.

Now do this: copy the image link again, run my second script and choose webarchive.
You could still paste command-v to Apple Mail and the image show. The reason its possible
is because the image is webarchive object and not image. If you do not believe me
test to paste in TextEdit nothing will happen. (we earlier remove public.tiff and set it to webarchive)

The reason I did this are to know exactly what kind of object will be paste object.

If you copy a image in Safari and paste it to Mail it will be tiff object it will be the same result
as webarchive. So this example maybe do not matter but to understand rtf or styled text
or what Pages store in rtf… and so on… Its not straightforward whats going on and more a
guessing I do not like.

Shane, I’m a strong believer html5, css and JavaScript could be a wonderful approach for email editor. So I’m looking into the approach if its possible to make emails in Safari. And use Apple mail to send the email. I got the idea when I understood it was possible to send webarchive to Apple Mail.

Safari is build to handle html5, css and JavaScript so it make sense to me.

Shane I have also been using this application to know more about pasteboard.
https://langui.net/clipboard-viewer/