Bug AppleScript: je ne parviens pas à convertir du texte enrichi en texte brut

3

J'ai créé un fichier AppleScript (.scpt) intitulé " Tapez Presse-papiers comme texte simple sur une seule ligne "Le script est déclenché par un raccourci clavier défini par FastScripts.

Comportement désiré:

Je veux que ce script prenne le contenu du presse-papiers, supprime toute la mise en forme, puis supprime les sauts de ligne ou les tabulations de ce texte. Enfin, je veux que le script tape le nouveau texte. Je veux préserver - pas écraser - le contenu d'origine du presse-papiers.

Le problème spécifique:

L'erreur spécifique est que mon script ne parvient pas à supprimer toute la mise en forme d'un texte enrichi.

Je ne peux pas inclure le contenu en texte intégral dans une publication Stack Exchange. Par conséquent, pour être témoin de mon problème, veuillez télécharger ce fichier .rtf via Dropbox . Ouvrez ce fichier dans TextEdit.app. Mettez en surbrillance la phrase et copiez-la dans le presse-papiers. Ensuite, déclenchez mon script alors que votre curseur est sous une forme qui prend en charge et affiche le texte enrichi (pour que vous puissiez voir que le script va taper du texte enrichi).

Vous remarquerez que la phrase tapée est un contenu en texte enrichi et qu'elle contient encore des éléments de mise en forme. Ces éléments incluent la police de texte d'origine (Helvetica) et la taille de la police d'origine (12). Ces éléments auraient dû être jetés. Ainsi, soit mon code est négligent, soit j'ai trouvé un véritable bogue dans AppleScript même. Je suppose que c'est le dernier.

Le code le plus court nécessaire pour reproduire l'erreur:

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:

Premièrement, quelqu'un peut-il confirmer que le problème mentionné se produit sur son ordinateur?

Si tel est le cas, comment puis-je supprimer tout formatage de texte enrichi dans AppleScript, en tenant compte de ce bogue que j'ai découvert?

rubik's sphere
la source
1
Les questions cherchant de l'aide pour le débogage ("pourquoi ce code ne fonctionne-t-il pas?") Doivent inclure le comportement souhaité, un problème ou une erreur spécifique et le code le plus court nécessaire pour le reproduire dans la question elle-même. Les questions sans énoncé clair du problème ne sont pas utiles aux autres lecteurs. Voir: Comment créer un exemple Minimal, Complete et Verifiable .
grg
Une chose que vous avez dite, " Ensuite, déclenchez mon script lorsque votre curseur est sous une forme qui prend en charge et affiche le texte enrichi. ", pourriez-vous fournir et exemple de cela" forme ", qui est accessible à tous?
user3439894
@ user3439894 Ce que je voulais dire par cette phrase est qu'il faut évidemment "Taper du texte brut sur une seule ligne" sous une forme qui affiche la mise en forme de texte enrichi s'ils veulent voir le bogue (c'est-à-dire la mise en forme de texte enrichi du résultat du script). Sinon, le bogue serait masqué, car vous verriez automatiquement le texte brut du résultat du script. Par exemple, un document Microsoft Word, un document TextEdit .rtf et un message électronique indiqueraient le formatage du texte enrichi. Un commentaire ou une réponse Stack Exchange ne le serait pas.
rubik's sphere
@grgarside Je viens de modifier ma question afin qu'elle soit conforme aux règles relatives au débogage.
rubik's sphere

Réponses:

2

Parce que the clipboard commande ajouter automatiquement d'autres types, testez ce script:

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

le résultat est - & gt; {{Unicode text, 10}, {string, 5}, {styles de scrap,   22}, {«class utf8», 5}, {«class ut16», 12}, {styles de scrap, 22}}


Pour éviter les styles, utilisez le NSPasteboard méthodes de:

-- *** 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:
jackjr300
la source
2

Tester avec votre code puis avec mon propre AppleScript simple code , Je peux reproduire le comportement (non désiré) à un point tel que je conviendrais que ce comportement n’est pas ce qu’on souhaite et peut être considéré comme un bogue, mais la solution de contournement est un peu un kludge.

Dans cette méthode, au lieu de définir theClipboardTextWithoutAnyLineBreaksOrFormatting directement dans le presse-papier, parce que c'est là le problème , il va être écrit dans un fichier temporaire, puis placé dans le Presse-papiers en utilisant pbcopy dans un do shell script commander puis le fichier temporaire est supprimé. Ensuite, il peut être collé au point d'insertion cible.

Pour tester la solution de contournement code ci-dessous, commentez le set the clipboard to theClipboardTextWithoutAnyLineBreaksOrFormatting ligne et puis placez la solution de contournement code directement après et avant la tell application "System Events" to keystroke "v" using {command down} ligne.

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
user3439894
la source
Votre solution résout le problème, de même que la solution fournie par @ jackjr300: le texte réellement clair du contenu du presse-papiers est dactylographié. Pourquoi dites-vous que cela "pourrait être considéré comme un bug"? Le comportement AppleScript que j’ai décrit assez clairement n’est-il pas un bug, puisqu’on déclare une variable as text, une police de texte riche et sa taille ne doivent pas être conservées?
rubik's sphere
La sphère de @ rubik, la raison pour laquelle j'ai formulé cela comme je l'ai fait est parce que je me concentrais davantage sur une solution de contournement que sur le problème lui-même. Est-ce que je considère que c'est un bug, oui! Vous devriez déposer un rapport de bogue à Apple à ce sujet.
user3439894
D'ACCORD. Je n'ai aucune expérience avec d'autres langages de programmation. AppleScript semble-t-il avoir plus de bugs que d'autres langages? Vous et moi avons personnellement découvert plusieurs petits bugs comme celui-ci dans AppleScript, et je suis simplement curieux de savoir si cela correspond au cours.
rubik's sphere