3

I created an AppleScript (.scpt) file entitled "Type Clipboard As Single Line Plain Text." The script is triggered by a keyboard shortcut set by FastScripts.

Desired behavior:

I want this script to take the clipboard contents, remove all formatting, and then remove any line breaks or tabs from this text. Finally, I want the script to type the new text. I want to preserve -- not overwrite -- the original clipboard contents.

The specific problem:

The specific error is that my script fails to remove all formatting from some rich text.

I cannot include full rich text content in a Stack Exchange post. Therefore, to witness my exact issue, please download this .rtf file via Dropbox. Open this file up in TextEdit.app. Highlight the sentence and copy it to the clipboard. Then, trigger my script while your cursor is in a form that supports and shows rich text (so that you can see that the script will type rich text).

You will notice that the typed sentence is rich text content and still contains formatting elements. These elements include the original text font (Helvetica) and the original font size (12). These elements should have been discarded. Thus, either my code is negligent or I have found a genuine bug within AppleScript itself. I am assuming that it is the latter.

The shortest code necessary to reproduce the error:

use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "AppKit"

-- Back up clipboard contents:
set savedClipboard to my fetchStorableClipboard()

(*
    Converting the clipboard text to plain text to remove any formatting:
    From: http://lifehacker.com/127683/clear-text-formatting-on-os-x
*)
set theClipboardTextWithoutAnyFormatting to (the clipboard as text)

(*
    Removing line breaks and indentations in clipboard text:
    From: http://stackoverflow.com/a/12546965 
*)
set AppleScript's text item delimiters to {return & linefeed, return, linefeed, character id 8233, character id 8232}
set theClipboardTextWithoutAnyFormatting to text items of (theClipboardTextWithoutAnyFormatting as text)
set AppleScript's text item delimiters to {" "}
set theClipboardTextWithoutAnyLineBreaksOrFormatting to theClipboardTextWithoutAnyFormatting as text

set the clipboard to theClipboardTextWithoutAnyLineBreaksOrFormatting
tell application "System Events" to keystroke "v" using {command down}
delay 0.1 -- Without this delay, may restore clipboard before pasting.
-- Restore the original clipboard:
my putOnClipboard:savedClipboard

on fetchStorableClipboard()
    set aMutableArray to current application's NSMutableArray's array() -- used to store contents
    -- get the pasteboard and then its pasteboard items
    set thePasteboard to current application's NSPasteboard's generalPasteboard()
    -- loop through pasteboard items
    repeat with anItem in thePasteboard's pasteboardItems()
        -- make a new pasteboard item to store existing item's stuff
        set newPBItem to current application's NSPasteboardItem's alloc()'s init()
        -- get the types of data stored on the pasteboard item
        set theTypes to anItem's types()
        -- for each type, get the corresponding data and store it all in the new pasteboard item
        repeat with aType in theTypes
            set theData to (anItem's dataForType:aType)'s mutableCopy()
            if theData is not missing value then
                (newPBItem's setData:theData forType:aType)
            end if
        end repeat
        -- add new pasteboard item to array
        (aMutableArray's addObject:newPBItem)
    end repeat
    return aMutableArray
end fetchStorableClipboard

on putOnClipboard:theArray
    -- get pasteboard
    set thePasteboard to current application's NSPasteboard's generalPasteboard()
    -- clear it, then write new contents
    thePasteboard's clearContents()
    thePasteboard's writeObjects:theArray
end putOnClipboard:

First, can someone confirm that the stated issue occurs on their computer?

If so, how can I remove all formatting of rich text in AppleScript, accounting for this bug that I've discovered?

  • 1
    Questions seeking debugging help ("why isn't this code working?") must include the desired behavior, a specific problem or error and the shortest code necessary to reproduce it in the question itself. Questions without a clear problem statement are not useful to other readers. See: How to create a Minimal, Complete, and Verifiable example. – grg Feb 15 '17 at 13:59
  • One thing you said, "Then, trigger my script while your cursor is in a form that supports and shows rich text.", could you provide and example of this "form", which is accessible to all? – user3439894 Feb 15 '17 at 15:12
  • @user3439894 What I meant by that sentence is that one must obviously "Type As Single Line Plain Text" in a form that shows rich text formatting if they wanted to witness the bug (i.e., the rich text formatting of the script result). Otherwise, the bug would be masked, as you would automatically see the plain text of the script result. For example, a Microsoft Word document, a TextEdit .rtf document, and an email message would show rich text formatting. A Stack Exchange comment or answer would not. – rubik's sphere Feb 15 '17 at 18:56
  • @grgarside I've just edited my question so that it is in line with the rules on debugging questions. – rubik's sphere Feb 15 '17 at 19:36
2

Because the clipboard command add others types automatically, test this script:

set the clipboard to "hello" as string
delay 1
return clipboard info

the result is --> {{Unicode text, 10}, {string, 5}, {scrap styles, 22}, {«class utf8», 5}, {«class ut16», 12}, {scrap styles, 22}}


To avoid the styles, use the NSPasteboard's methods:

-- *** add the missing lines from your script here  ***
--- set the clipboard to theClipboardTextWithoutAnyLineBreaksOrFormatting -- don't use this command to avoid the scrap styles type.
my putTextOnClipboard:theClipboardTextWithoutAnyLineBreaksOrFormatting -- use this method to put some string in the clipboard.

tell application "System Events" to keystroke "v" using {command down}
delay 0.1 -- Without this delay, may restore clipboard before pasting.
-- Restore the original clipboard:
my putOnClipboard:savedClipboard


on putTextOnClipboard:t
    set thePasteboard to current application's NSPasteboard's generalPasteboard()
    thePasteboard's clearContents()
    thePasteboard's declareTypes:{current application's NSPasteboardTypeString} owner:(missing value)
    thePasteboard's setString:t forType:(current application's NSPasteboardTypeString)
    --> now the clipboard contains these types only: («class utf8», «class ut16», string and Unicode text)
end putTextOnClipboard:
2

Testing with your code and then with my own simple AppleScript code, I can reproduce the (unwanted) behavior to a point I'd agree the behavior is not what's wanted and might be considered a bug, however the workaround is a bit of a kludge.

In this method, instead of setting theClipboardTextWithoutAnyLineBreaksOrFormatting directly to the Clipboard, because that's where the issue is, it's going to be written to a temporary file, then placed on the Clipboard using pbcopy in a do shell script command and then the temporary file is deleted. Then it can be pasted to the target insertion point.

To test the workaround code below, comment out the set the clipboard to theClipboardTextWithoutAnyLineBreaksOrFormatting line and then place the workaround code directly after it and before the tell application "System Events" to keystroke "v" using {command down} line.

set tempFileToRead to POSIX path of (path to desktop) & ".tmpfile"
try
    set referenceNumber to open for access tempFileToRead with write permission
    write theClipboardTextWithoutAnyLineBreaksOrFormatting to referenceNumber
    close access referenceNumber
on error eStr number eNum
    display dialog eStr & " number " & eNum buttons {"OK"} default button 1 with title "File I/O Error..." with icon caution
    try
        close access referenceNumber
    end try
    return
end try
do shell script "pbcopy<" & tempFileToRead & "; rm " & tempFileToRead
  • Your solution solves the issue, and the solution provided by @jackjr300 does as well: the truly plain text of the clipboard contents is typed. Why do you say that this "might be considered a bug"? Isn't the AppleScript behavior that I described pretty clearly a bug, since when one declares a variable as text, a rich text font and font size should not be retained? – rubik's sphere Feb 16 '17 at 10:16
  • @rubik's sphere, The reason I phrased it in the manner I did is because I was focused more on a workaround to the issue then the issue itself. Do I consider it a bug, yes! You should file a bug report to Apple on it. – user3439894 Feb 16 '17 at 13:16
  • OK. I have no experience with any other programming languages. Does AppleScript seem to have more bugs than other languages? You and I have personally discovered multiple little bugs like this in AppleScript, and I'm just curious if this is par for the course. – rubik's sphere Feb 16 '17 at 18:26

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .