I have a use-case where I want my application to store clipboard data and later allow the user to paste it out.
The thing is - I want to both support HTML-styled text (while maintaining its styling) and also support simple plain-text.
What I have so far is:
Pasteboard variable setup
let pasteboard = NSPasteboard.general
pasteboard.declareTypes([.html, .string], owner: nil)
Storing user's clipboard data
let copiedString = pasteboard.string(forType: .html) ?? pasteboard.string(forType: .string) {
If, for example, a user copies text from the browser, this method maintains the entire HTML.Alternatively, if text is being copied from applications that don't support HTML (such as XCode, Notes, etc), `copiedString` will simply hold the plain text.
Later down the line - pushing contents back to clipboard
pasteboard.setString(copiedString, forType: .html)
My problem is, when I try to paste the content pushed into my clipboard; it only works in applications that actually support HTML-formatted text, such as Chrome / Microsoft Word.
When I try to paste the content into XCode for example, it simply doesn't spit out anything.
Ideally, I want my clipboard to adjust itself according to the application I'm on - paste the text as HTML if supported by the application, otherwise - paste the plain text.
How can I implement such behavior?
Thanks!
Related
I searched a lot but couldn't get the answer.
I want to retain copied text from pdf to WYSIWYG editor(Ckeditor).
I can retain style while copied from Word files but it does not work the same way when copied from PDF.
Original pdf is like this(I can't post image as reputation is < 10 , please refer links):
PDF text
It shows following output after copy paste:
After copy paste in WYSIWYG editor
Please suggest plugin or code snippet for PDF to RTF conversion.
Thanks
CKEditor can paste only data which it gets from the browsers. It means that if browsers do not provide more data then the plain text there is nothing CKEditor can do.
Since version 4.5 CKEditor provide facade to handle Clipboard API and get all data which are pasted directly in the paste event. Every browser provide different data and you can easily check them:
editor.on( 'paste', function( evt ) {
var types = evt.data.dataTransfer.$.types;
console.log( types );
for ( var i = 0; i < types.length; i++ ) {
console.log( evt.data.dataTransfer.getData( types[ i ] ) );
}
// Additionally you can get information about pasted files.
console.log( evt.data.dataTransfer.getFilesCount() );
} );
Note that Internet Explorer does not provide types array and support only Text and URL types.
To learn more about Clipboard Integration see this guide. Especially "Handling Various Data Types with Clipboard API" chapter which describe how to integrate data converter with the paste event, so if the PDF data are available in any browser you can use them during pasting.
If it's a common case in your system then imho the best thing you can do is to allow users to upload the PDF file, run server side software to transform PDF into HTML and then automatically insert it into CKEditor.
I have no recommendations though on which application to use.
The problem is that PDF files work in a different way that other text documents, so even if you try to paste its contents into a native word processor you won't get the same formatting.
This will vary depending on your PDF reader, but it's usual that images aren't pasted, tables are converted to plain text lines, etc...
If that happens in a native program that has full access to the clipboard, you can't expect anything better in a javascript application that depends on the data that the browser provides, and even after that you have to be careful with CKEditor because by default it includes filters to remove any formatting that it doesn't recognize so even more information can be lost at this last point.
I'm writing relatively complex iOS app that is very text heavy.
The text is also heavily formatted. It has lots of color, size, font, and spacing changes, as well bulleted lists and other text features you'd expect to see in a very rich website.
The text is displayed on about 40 different views. Some of which display a lot of text, others a little. There is no one template that all the pages follow. (There are some that are similar, but that's not the point.)
Lastly, the text is constantly being changed and updated by an editorial team during development, not so much after release. The text has to be stored on the device, downloading files is not an option.
My question is, what is the best way to store and then render all this text in an iOS App?
My approach
Store all the text content and formatting info in an html file and use
[[NSAttributedString alloc] initWithFileURL:htmlDoc
options:#{
NSDocumentTypeDocumentAttribute:NSHTMLTextDocumentType}
documentAttributes:&attrDict
error:&error];
to create a NSAttributed string and use that to populate UITextViews.*
*Note: I would do some more work before creating the UITextViews. First I would parse it to find the appropriate page number [[Page:1.3]] and then parse the elements in that section [[header]], [[side_scroller]], etc...
I like this approach for two main reasons:
It created a separate copy document that contained all the text
and formatting info.
I'm the only iOS developer, but we have a couple front-end
developers. So when we get slammed with changes that need to be done
in 3.45 minutes, I could have some of the guys help me make the
changes, without having to know all the nuances of UIFont and
related classes. Occasionally, the editors could even make the
changes themselves :)
Minor reasons for liking this approach:
The text can vary so much per page, that creating a new UIFont + Plist entry to store the formatting info seems like a bigger pain than having everything in a .html document. (I could be wrong about this.)
Project managers will inevitably say: "Make this word a little bigger," "This word looks strange, add italics," and "Make everything purple!" HTML/CSS seems like a more flexible solution for quickly implementing these requests.
Downsides of this approach:
NSAttributedString picks up 99% of the HTML attributes I threw at it. It did not pick bullet spacing changes in unordered lists <ul>.
Plists are more performant.
Here are some other approaches I considered:
Plist + UIFont
RTF Document - Originally started with this, but found it hid a lot of what was going on and NSAttributedString wouldn't pick up some of the changes.
XML
Any advice or input would very appreciated.
Notes:
iPad app,
iOS 7,
No Internet Connectivity,
Xcode 5
What I did to store styled text in an iOS app was to write a Mac OS command line tool that opens RTF files and converts them to attributed strings (It's a 1-line call in Mac OS, but not supported in iOS for some reason.) I then use NSCoding to save the attributed strings as binary data, with a special .DATA filetype.
I created a custom UITextView category with a method that knows how to load the text view's attributed text from my custom filetype.
I created a build rule in my project that treats RTF files as source files in a build step and the .DATA filetype as the output, and copies the .DATA files into the build project.
Now, all I have to do is add an RTF file to my project the build process inserts the .DATA version of the styled text into the executable.
The Xcode editor knows how to edit RTF files, so you can edit them right in place in the IDE, OR you can edit them in TextEdit or any editor that supports RTF files.
There are a few things you can put in an RTF that aren't supported in UITextViews. (I don't remember what those are offhand. Sorry.)
I find styled WYSIWYG text much easier to deal with than HTML. You just edit the text, and the build process picks up the changes.
It worked beautifully. Plus, binary NSCoding output is a whole lot more compact than HTML.
I would recommend using web view. It can open files in resource bundle.
You can disable all the links in HTML by implementing delegate method shouldStartLoadWithRequest to return NO.
You might also want to set dataDetectorTypes to UIDataDetectorTypeNone.
That will disable auto link detection in web view
I have seen on few websites that when you copy some text from there, and paste anywhere, it will add the URL of the page from where I copied the text.
For example:
This is text I copied.
and when I paste, I get:
This is text I copied.
Read more: http://example.com/abc/def
I'm just curious to know how this is done? How to add additional text in the copied text?
Example: Check this question (or any other) on answers.com. Copy the question text and paste. Tested with Firefox latest version.
There are many online tools which provide this and other website/blog management utilities. Answer.com is also using one such service named tynt. Open the link, scroll down to the bottom and you can see answer.com in featured clients ;).
For more information.
Zeroclipboard should help you modify the clipboard content. It's a flash movie that is hidden in the browser and exposes a JavaScript API to access the clipboard.
Example.
var clip = new ZeroClipboard.Client();
clip.addEventListener('complete', function(client, text) {
clip.setText(text + "Read more at www.");
});
I noticed that if you copy-paste web browser content into Notepad (or any text editor), you get different results, depending on the browser used.
That is, if you try the following:
Ctrl-A (while inside IE, Firefox,
Chrome, etc.)
Ctrl-C
Ctrl-V (inside Notepad)
You will see that the text content from Internet Explorer is different than the one from Firefox.
(I conducted this test on Windows XP and Windows 7)
Why is that?
Are web browsers free to use any algorithm they choose to convert HTML content to CF_TEXT?
If so, are there any "minimal rules" they must adhere to?
When you copy data from the browser, the browser is responsible for converting data into the various clipboard formats. Since all of these data conversions can be expensive, most browsers will defer the conversion until a call is made to retrieve the clipboard data. According to MSDN, this is accomplished by calling SetClipboardData with a NULL for the second parameter. When a later call is made to GetClipboardData, the browser receives a WM_RENDERFORMAT or WM_RENDERALLFORMATS message. It is at this point that the browser performs the conversion to text. There are no particular rules that the browser must follow when performing this conversion.
I'm attempting to send HTML formatted emails using C# 3 via Outlook.MailItem
Outlook.MailItem objMail = (Outlook.MailItem)olkApp.CreateItem(Outlook.OlItemType.olMailItem);
objMail.To = to;
objMail.Subject = subject;
objMail.HTMLBody = htmlBody;
The email is generated externally by saving from an RTF control (TX Text Control), which yields HTML with links to images stored in a <<FileName>>_files subdirectory. Example:
<img border="0" src="file:///C:/Documents%20and%20Settings/ItsMe/Local%20Settings/Temp/2/zbt4dmvs_Images/zbt4dmvs_1.png" width="94" height="94" alt="[image]">
Sending the email this way generates a mail with broken links.
Using Outlook 2007 as the email client with Word as the email editor, switching to RTF (Options tab, Format tab group) preserves the layout and inlines the images.
Programmatically doing this via:
var oldFormat = objMail.BodyFormat;
objMail.BodyFormat = Outlook.OlBodyFormat.olFormatRichText;
objMail.BodyFormat = oldFormat;
loses the formatting and mangles the images (the image becomes a [image] link marker on screen which is clickable but no longer shows the image). This isn't a surprise given that the documentation for MailItem.BodyFormat Property says "All text formatting will be lost when the BodyFormat property is switched from RTF to HTML and vice-versa".
Sadly there doesnt seem to be an easy way to change the Type of each Attachment in the MailItem.Attachements to OlAttachmentType.olByValue, as it's a read-only property that's set when you create the Attachment.
An approach that comes to mind is to walk the HTML, replacing the <img> tags with markers and programatically walking the MailItem text, inserting an Outlook.Attachment of Type OlAttachmentType.olByValue.
Another option is to convert the <img> links to use src="cid:uniqueIdN" and add the images as attachments with the referenced identities.
So, to the question... Is there a way to get the linked images converted to embedded images, ideally without getting into third party tools like Redemption? Converting to RTF happens to yield the outcome, but doing it that way is by no means a pre-requisite, and obviously may lose fidelity - I Just Want It to Just Work :D Neither of my existing ideas sound Clean to me.
Since you are using .net > 2.0, you may want to look into the System.Net.Mail namespace for the creation of mail messages. I have found that its quite customizable and was very easy to use for a task similar to yours. The only problems that I had was making sure I was using the right encoding, and I had to use HTML tables for layouts (css would not work right). Here are some links to show you how this works...
Basic
With multiple views (Plain Text and HTML)
If that's not an option, then I would recommend going the Content ID route and embedding the images as attachments. Your other option is to host the images publicly on a website, and change the image links in the html to the public images.
Something that you should be cognizant about is that HTML emails can easily look like spam and can be treated as such by email servers and clients. Even ones that are just for in-house usage (its happened to me) can end up in Outlook's Junk Mail folder..
DOH!, actually sending the email in Outlook 2007 forces the images to become embedded.
The Sent Item size of 8K is a lot smaller than the draft size of 60K (RTF) I was seeing vs the draft size of 1K (HTML that hadn't been converted to RTF and back again).
So it was Doing What I Mean all the time. Grr.
I'll leave the Q and the A up here in case it helps someone of a similarly confused state of mind.
BTW some useful links I found on my journey:
Sending emails example
General Q&A site with other examples of varying quality