0

Is it possible to convert an NSattributedString with attachments (RTFD not RTF) to ASCII, edit the stream, and convert it back? So far I am able to convert an RTFD to a String stream. But turning it back into an NSData object does not work. Here's the code I'm using in a playground.

import Cocoa

func stream(attr: NSAttributedString) -> String? {
    if let d = attr.rtfd(from: NSMakeRange(0, attr.length), documentAttributes: [NSDocumentTypeDocumentAttribute: NSRTFDTextDocumentType]) {
        if let str = String(data: d, encoding: .ascii) { return str }
        else {
            print("Unable to produce RTFD string")
            return nil
        }
    }
    print("Unable to produce RTFD data stream")
    return nil
}


if let im = NSImage(named: "image.png") {
    let a = NSTextAttachment()
    a.image = im

    let s = NSAttributedString(attachment: a)

    if let str = stream(attr: s) {
        print("\(str)\n") //prints a string, which contains RTF code combined with NSTextAttachment string representation

        if let data = str.data(using: .ascii) { //this is where things stop working
            if let newRTF = NSAttributedString(rtfd: data as Data, documentAttributes: nil) {
                print(newRTF)
            }
            else { print("rtfd was not created") }
        }
        else { print("could not make data") }
    }
}

What am I missing? Or is my entire concept wrong here? I am doing this to get around a limitation of the way OS X handles images attached in RTF documents.

Edit: The limitation I am trying to address is to set the size of an image in an RTF stream. The text handling system requires that we use NSTextAttachment. Whenever an image is pasted from that, it automatically sizes the image to whatever the pixel height and width are. Unfortunately there is no way to control this property. I have tried here and also using all the techniques here.

As far as the ASCII stream, I'm not trying to edit the image attachment itself. When the stream is printed, the actual RTF code is visible and editable. This works and would be a good workaround for this limitation. All I need is to edit the RTF code and change the \width and \height properties that Apple uses.

Community
  • 1
  • 1
MAH
  • 549
  • 4
  • 15
  • It seems unsurprising that this is failing, why would a Unicode string containing an encoding of an image be able to be convert losslessly to an ASCII string? It is not clear what you are trying to do here. You might be better off explaining whatever limitation you are concerned over and ask for guidance in addressing it. (You can edit the question or maybe better delete this one and create a new one, don't try to explain in comments.) – CRD Dec 09 '16 at 17:11
  • @CRD hello, I have updated the question to include more information per your request. If I am missing something conceptually and this is a very wrong approach then I am more than glad to learn. – MAH Dec 09 '16 at 17:17

1 Answers1

0

After your edit I can see what you are trying to do, interesting idea, but it won't work - at least not easily.

Take a look at the value of d, it is not an ASCII string stored as a value of type Data (or NSData). It is a serialised representation of multiple items; the RTF stream (text), the image data (binary). If you convert this to an ASCII string and back again it is not going to work, you can't represent arbitrary binary data as ASCII unless you encode it (e.g. something like base 64 encoding).

Now you could attempt what you are trying a slightly different way, skip the conversion to ASCII and edit the Data value directly. That is certainly possible, but as you are editing a format you don't know (the serialised representation) you would have to be careful... And even if you succeed in editing the representation there is no guarantee that converting back to an NSAttributedString with an NSTextAttachment will preserve your edits.

I suggest you tackle this another way. You have an NSAttributedString and you don't like the RTF produced after you write this to a file. So edit the RTF after it is written, e.g. open up the RTFD package, open the contained RTF file (TXT.rtf), edit it, write it back.

HTH

CRD
  • 50,500
  • 4
  • 64
  • 80
  • This is close. I've actually managed to encode to .macOSRoman encoding, edit, then convert back to NSAttributedString. Once converted back though, it always resets the image size. As far as I'm concerned this is basically impossible to solve. I have also tried changing the tags after the fact, in a rtf file but that also doesn't work. Cough it up for Apple to ignore one of the most important aspects of the RTF syntax which is images. For now I think I just have to scale the image before hand and lose a lot of resolution. – MAH Dec 10 '16 at 16:34