Bug di AppleScript: non riesco a convertire il rich text in testo normale

3

Ho creato un file AppleScript (.scpt) dal titolo " Digita appunti come linea singola testo semplice ." Lo script è attivato da una scorciatoia da tastiera impostata da FastScripts.

Comportamento desiderato:

Voglio che questo script prenda il contenuto degli appunti, rimuova tutta la formattazione e quindi rimuova eventuali interruzioni di riga o tab da questo testo. Infine, voglio che lo script digiti il nuovo testo. Voglio conservare - non sovrascrivere - il contenuto degli appunti originali.

Il problema specifico:

L'errore specifico è che il mio script non riesce a rimuovere tutta la formattazione da alcuni rich text.

Non riesco a includere il contenuto RTF completo in un messaggio Stack Exchange. Pertanto, per testimoniare il mio esatto problema, scarica questo file .rtf tramite Dropbox . Apri questo file in TextEdit.app. Evidenzia la frase e copiala negli appunti. Quindi, attiva il mio script mentre il tuo cursore si trova in una forma che supporta e mostra rich text (in modo che tu possa vedere che lo script digiterà rich text).

Noterai che la frase digitata è un contenuto RTF e contiene ancora elementi di formattazione. Questi elementi includono il carattere del testo originale (Helvetica) e la dimensione del carattere originale (12). Questi elementi avrebbero dovuto essere scartati. Pertanto, il mio codice è negligente o ho trovato un vero bug all'interno di AppleScript. Suppongo che sia quest'ultimo.

Il codice più breve necessario per riprodurre l'errore:

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:

In primo luogo, qualcuno può confermare che il problema dichiarato si verifica sul proprio computer?

Se sì, come posso rimuovere tutta la formattazione del rich text in AppleScript, tenendo conto di questo bug che ho scoperto?

    
posta rubik's sphere 15.02.2017 - 04:45
fonte

2 risposte

2

Poiché il comando the clipboard aggiunge automaticamente altri tipi, prova questo 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}}

Per evitare gli stili, utilizza i metodi NSPasteboard :

-- *** 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:
    
risposta data 16.02.2017 - 05:37
fonte
2

Test con il tuo codice e poi con il mio semplice code di AppleScript, posso riprodurre il comportamento (indesiderato) a un punto in cui sono d'accordo che il comportamento non è quello che è voluto e potrebbe essere considerato un bug, tuttavia la soluzione è un po 'di kludge.

In questo metodo, invece di impostare theClipboardTextWithoutAnyLineBreaksOrFormatting direttamente negli Appunti, perché è lì che il problema è , verrà scritto in un file temporaneo, quindi inserito negli Appunti utilizzando pbcopy in un do shell script comando e quindi il file temporaneo viene eliminato. Quindi può essere incollato al punto di inserimento del target.

Per testare la soluzione code qui sotto, commenta la riga set the clipboard to theClipboardTextWithoutAnyLineBreaksOrFormatting e poi metti la soluzione code direttamente dopo di essa e prima della riga tell application "System Events" to keystroke "v" using {command down} .

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
    
risposta data 16.02.2017 - 04:32
fonte

Leggi altre domande sui tag