7 votes

Comment utiliser AppleScript pour créer un nouveau fichier Rich Text Format à partir du texte du presse-papiers ?

J'ai un service Automator qui prend le texte actuel dans le presse-papiers et l'écrit dans un nouveau fichier .txt. Cette opération est exécutée simplement avec le code AppleScript suivant :

do shell script "pbpaste > /path/to/your/clipboard-file.txt"

Ce code provient de la réponse suivante de Stack Overflow :

AppleScript pour coller du texte du presse-papiers dans un fichier

Cependant, ce code convertit le contenu du presse-papiers en texte brut, en supprimant toutes les mises en forme du texte.

Est-il possible d'utiliser AppleScript pour écrire le contenu du presse-papiers dans un fichier .rtf ou .rtfd, tout en préservant le formatage original du contenu du presse-papiers ? Par formatage original, je fais référence aux données stylistiques telles que l'accentuation typographique (gras, italique, souligné), la taille de la police et la couleur du texte.

Sur un coup de tête, j'ai essayé la commande suivante :

do shell script "pbpaste > /path/to/your/clipboard-file.rtf"

Mais cette commande a donné lieu à un fichier .rtf que mon ordinateur n'a pas pu lire ou ouvrir.

12voto

user3439894 Points 52496

Cette réponse a été mise à jour pour refléter rubik's sphere's malentendu entre ce qu'est le texte enrichi (ce qui a été demandé à l'origine) et ce qui est réellement utilisé par Google Chrome, à savoir le HTML. (Voir les commentaires déplacés vers chat .)

Je laisse la réponse originale telle quelle, et je mets en dessous ce nouveau contenu, car il répond techniquement à la question originale telle qu'elle a été posée. Il contient également des informations pertinentes pour le processus global de traitement du contenu du presse-papiers dans le contexte de la question originale et modifiée.

Le site code Voici un exemple code pour être testé et exécuté dans (Apple) script Editor, car à part la première phrase de la question, aucune utilisation explicite et spécifique dans Automator n'a encore été donnée. Le site code devra peut-être être modifié pour fonctionner dans le cadre d'une utilisation inconnue dans Automator. Cela dit, tel qu'il est écrit, si l'ensemble de la script ci-dessous a été placée toute seule dans une action Run AppleScript, toute seule, dans Automator... elle fonctionne telle quelle. Si vous n'utilisez que des segments du code certains changements apportés au système existant code pourrait avoir besoin d'être fait.

Le site code ci-dessous contient suffisamment de commentaires pour permettre de comprendre globalement ce que le script fait.


--        # 
--        # Change the 'New RichText Filename.rtf' name to the wanted filename for the target file.
--        # Make sure you leave the double-quotes even if the filename does not contain spaces!
--        # Note that '(path to desktop as text)' can also be modified as needed, e.g. changed to,
--        # '(path to documents folder as text)' or the entire segment after 'set theRichTextFileName to'
--        # can be a fully qualified POSIX pathname, e.g.: set theRichTextFileName to "/path/to/filename.rtf"
--        #  

set theRichTextFileName to POSIX path of (path to desktop as text) & "New RichText Filename.rtf"

--    #        THE REMAINING CODE SHOULD NOT NEED TO BE MODIFIED.
--    # 
--    #     Note: This code, as is, works as written and intended when run from within (Apple) Script Editor.
--    #     Some AppleScript code when wrapped in Automator may not work the same as in (Apple) Script Editor.
--    #     In cases where is does not work from a Run AppleScript action in Automator, editing will be required.
--    # 
--    #     This AppleScript code preforms the following actions, sans errors caught during File I/O operations.
--    # 
--    # 1. See it the target file exists and prompts to be overwritten if it does. If yes is selected, it continues.
--    # 
--    # 2. If the Clipboard contains RTF content, writes it to the target file using plain AppleScript.
--    # 
--    # 3. If the Clipboard contains HTML content, writes it to the target file as RTF using a 'do shell script' command.
--    # 
--    # 4. If the Clipboard does not contain any RTF/HTML content, notify the user. 
--
--        #    Notes: The 'do shell script' makes use of the following:
--        #
--        #    'osascript' to get the HTML content from the Clipboard.
--        #    The content is a Hex stream within a data wrapper and
--        #    'awk' will be used to remove/replace the data wrapper.
--        #
--        #    'awk' to remove the data wrapper from 'osascript' output
--        #    replacing it with proper HTML opening/closing Tags to
--        #    ensure it actually gets processed by 'textutil' after 'xxd'.
--        #    Without the HTML opening/closing Tags 'textutil' does not 
--        #    properly, within limits, convert the HTML Clipboard content to RTF.
--        #
--        #    'xxd' to convert the Hex data from 'osascript/awk' to ASCII text.
--        #
--        #    'textutil' to convert the ASCII text HTML from 'xxd' to RTF
--        #    formatted data and write it to the target file.

tell application "Finder"

    if exists theRichTextFileName as POSIX file then
        tell current application
            display dialog "The file \"" & theRichTextFileName & "\" already exists!" & "\n\n" & "Do you want to overwrite the file?" buttons {"No", "Yes"} default button 1 with title "File Already Exists..." with icon caution

            if the button returned of the result is "No" then
                return
            else
                tell application "Finder"
                    delete the file (theRichTextFileName as POSIX file)
                end tell
            end if
        end tell
    end if

    tell current application

        --    # Find out what class types are available for the Clipboard content
        --    # and use this information to determine which action will be taken.

        set cbInfo to get (clipboard info) as string

        if cbInfo contains "RTF" then

            try
                set richTextfromClipboard to get the clipboard as «class RTF »
            on error eStr number eNum
                display dialog eStr & " number " & eNum buttons {"OK"} default button 1 with icon caution
                return
            end try
            try
                set fileHandle to open for access theRichTextFileName with write permission
                write richTextfromClipboard to fileHandle
                close access fileHandle
            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 fileHandle
                end try
            end try

        else if cbInfo contains "HTML" then

            try
                do shell script "osascript -e 'try' -e 'get the clipboard as «class HTML»' -e 'end try' | awk '{sub(/«data HTML/, \"3C68746D6C3E\") sub(/»/, \"3C2F68746D6C3E\")} {print}' | xxd -r -p | textutil -convert rtf -stdin -stdout > " & quoted form of theRichTextFileName
            on error eStr number eNum
                display dialog eStr & " number " & eNum buttons {"OK"} default button 1 with icon caution
            end try

        else

            display dialog "The Clipboard does not contain\nany usable RTF/HTML content!" buttons {"OK"} default button 1 with title "No RTF/HTML Content on Clipboard..." with icon caution

        end if

    end tell

end tell

Réponse originale à la question originale posée :

Pour obtenir Texte enrichi contenu de la Presse-papiers en un fichier en utilisant AppleScript c'est un peu plus complexe qu'un simple do shell script commande .

L'exemple AppleScript code ci-dessous, si la cible fichier n'existe pas déjà et si Texte enrichi contenu existe sur le Presse-papiers et l'écrire dans un fichier . Il aura tous les attributs comme le RichText contenu sur le Presse-papiers a, comme il l'a fait lors de la copie dans le Presse-papiers .

Ouvrir scriptÉditeur et copier et coller le code ci-dessous dans un nouveau Sans titre puis l'exécuter à partir de scriptÉditeur en passant en revue les sortie sur Événements/Réponses . Faites-le tourner plusieurs fois, avec et sans Texte enrichi contenu sur le Presse-papiers et avec et sans l'existence de la fichier sur le disque dur, défini par set theRichTextFileName ... au début de la script .

Vous verrez le code s'assure que le fichier n'existe pas, afin de ne pas écraser une version existante de fichier du nom et de l'emplacement de la cible et si le Presse-papiers ne contient pas Texte enrichi contenu il affiche un message pour cela aussi.

Maintenant, si vous utilisez ceci dans un Automator Service par exemple, où Le service reçoit le texte riche sélectionné alors le code peut être modifié pour ne pas piéger une erreur si Texte enrichi contenu n'est pas sur le Presse-papiers comme le service n'apparaîtra pas sur le Services menu si Texte enrichi n'est pas sélectionné dans un document. De même, si vous souhaitez écraser la cible fichier à son emplacement désigné, le code autour d'elle peut aussi être enlevée. Je vais donner à ces code également des exemples.


Exemple code à coller dans scriptÉditeur pour être testé et examiné :

set theRichTextFileName to POSIX path of (path to documents folder as text) & "New RichText Filename.rtf"

tell application "Finder"
    if exists theRichTextFileName as POSIX file then
        tell current application
            display dialog "The file \"" & theRichTextFileName & "\" already exists!" buttons {"OK"} default button 1 with title "File Already Exists..." with icon caution
        end tell
    else
        tell current application
            try
                set richTextfromClipboard to get the clipboard as «class RTF »
            on error eStr number eNum
                display dialog eStr & " number " & eNum buttons {"OK"} default button 1 with title "No Rich Text Content on Clipboard..." with icon caution
                return
            end try
            try
                set fileHandle to open for access theRichTextFileName with write permission
                write richTextfromClipboard to fileHandle
                close access fileHandle
            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 fileHandle
                end try
                return
            end try
        end tell
    end if
end tell

Exemple code à utiliser dans un Automator Service par exemple, où Le service reçoit le texte riche sélectionné :

set theRichTextFileName to POSIX path of (path to documents folder as text) & "New RichText Filename.rtf"

tell application "Finder"
    if exists theRichTextFileName as POSIX file then
        tell current application
            display dialog "The file \"" & theRichTextFileName & "\" already exists!" buttons {"OK"} default button 1 with title "File Already Exists..." with icon caution
        end tell
    else
        tell current application
            set richTextfromClipboard to get the clipboard as «class RTF »
            set fileHandle to open for access theRichTextFileName with write permission
            write richTextfromClipboard to fileHandle
            close access fileHandle
        end tell
    end if
end tell

Exemple code à utiliser dans un Automator Service par exemple, où Le service reçoit le texte riche sélectionné et écrase la cible existante fichier :

set theRichTextFileName to POSIX path of (path to documents folder as text) & "New RichText Filename.rtf"

tell current application
    set richTextfromClipboard to get the clipboard as «class RTF »
    set fileHandle to open for access theRichTextFileName with write permission
    write richTextfromClipboard to fileHandle
    close access fileHandle
end tell

L'image ci-dessous est un exemple Automator Service qui crée le Nouveau nom de fichier RichText.rtf fichier à partir d'une sélection de Texte enrichi de la Créer un fichier Rich Text à partir du presse-papiers service sur le Menu contextuel des services (par un clic droit) ou Nom de l'application > Services > menu quand Texte enrichi est sélectionné dans un document.

Automator Service - Create Rich Text file from Clipboard


Il ne s'agit là que d'exemples et il est possible de coder une logique supplémentaire pour l'adapter aux besoins de chacun. A titre d'exemple, code pourrait être ajouté pour incrémenter automatiquement le nom d'un fichier existant afin de ne pas l'écraser, ou demander un nouveau nom de fichier et terminer l'opération au lieu d'abandonner avec un message indiquant que le fichier existe déjà, etc.


Mise à jour pour utilisation avec un do shell script commande :

Si vous voulez vraiment le faire en utilisant un do shell script commande alors utilisez la formule suivante code tout en remplaçant /path/to/new rich text file.rtf avec un chemin, nom de fichier à un endroit où vous avez les droits d'écriture. Notez que vous ne devez pas supprimer le \" avant et après /path/to/new rich text file.rtf dans la réalité commande car il gère le chemin, nom de fichier s'il contient des espaces. Si le chemin, nom de fichier ne contient pas d'espaces, alors le \" avant et après /path/to/new rich text file.rtf n'a pas besoin d'être utilisé.

do shell script "osascript -e 'try' -e 'get the clipboard as «class RTF »' -e 'end try' | awk '{print substr($0, 12, length($0)-13)}' | xxd -r -p > \"/path/to/new rich text file.rtf\""

Voici le commande qui s'affiche sous forme de texte enveloppé, pour une visualisation plus aisée :

do shell script "osascript -e 'try' -e 'get the clipboard as «class RTF »' -e 'end try' | awk '{print substr($0, 12, length($0)-13)}' | xxd -r -p > \"/path/to/new rich text file.rtf\""

  • Bien que l'on puisse copier et coller (recommander) l'adresse de l'entreprise. code Néanmoins, voici comment taper les guillemets à double angle, qui sont également disponibles sous Parenthèses dans Caractères (spéciaux), par ex. optioncommandT dans TextEdit.

    Note : Gardez à l'esprit l'espacement dans «class RTF » est destiné à être décalé dans ce cas d'utilisation.

    • Taper les guillemets à double angle

      • "Le guillemet gauche à double angle, appuyez : option\
      • "Guillemets droits à double angle, appuyez : shiftoption\

Notez que, tel qu'il est écrit, ce do shell script commande écrase le fichier de sortie s'il existe déjà, sans demande ! Il s'agira d'un fichier de longueur nulle si le Presse-papiers ne contient pas de contenu Rich Text, sinon le fichier aura la longueur nécessaire pour contenir le contenu Rich Text du Presse-papiers. Évidemment, une logique supplémentaire pourrait être codée dans la fonction osascript commande Cependant, si vous avez besoin de plus de complexité, il est préférable d'utiliser la méthode présentée en premier lieu dans cette réponse. Ou en utilisant un script externe appelé par do shell script commande qui gère toutes les logique y gestion des erreurs en fonction de la complexité des conditions générales dans lesquelles elle sera appliquée.

  • Pourquoi une telle complexité par rapport à l do shell script "pbpaste > /path/to/clipboard-file.rtf" ?

C'est une bonne question et bien que pbpaste a le -Prefer {txt | rtf | ps} Néanmoins, l'option pbpaste -Prefer rtf peut ne pas produire de texte enrichi même s'il existe dans le presse-papiers. Ou ce qu'il produit, s'il ne s'agit pas de texte ASCII, ne sera pas une forme de texte enrichi comprise, par exemple, par TextEdit, et ne contiendra pas tout le texte enrichi. attributs le cas échéant, que le contenu du presse-papiers contient.

Il est donc nécessaire d'obtenir le contenu du texte riche sur le presse-papiers d'une manière différente et pourquoi get the clipboard as «class RTF » est utilisé à la place. Lorsque vous utilisez un do shell script commande avec cela, il faut un traitement supplémentaire pour utiliser la données renvoyée, car elle se trouve dans un enveloppe de données lorsqu'il est retourné et n'est pas immédiatement utilisable, il nécessite donc un traitement supplémentaire.

A titre d'exemple, Hello World! en texte riche dans le presse-papiers peut ressembler à ceci en texte ASCII :

{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf400
{\fonttbl\f0\fnil\fcharset0 ComicSansMS;}
{\colortbl;\red255\green255\blue255;}
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural

\f0\b\fs36 \cf0 Hello World!}

Le format ci-dessus n'est malheureusement pas facilement utilisable, voire pas du tout, dans AppleScript et je crois que c'est la raison pour laquelle il a été saisi sous forme de code hexadécimal. données est nécessaire.

  • Je me base sur le fait que, même si le get clipboard info commande pour le contenu du presse-papiers dans cet exemple renvoie {«class RTF », 265} parmi les informations renvoyées, néanmoins, alors que la forme texte ASCII de ce contenu riche en texte fait 265 octets, il est renvoyé au format hexadécimal, soit deux fois plus d'octets qu'avec l'adresse IP. enveloppe de données . Le fait qu'il soit renvoyé dans Hex par get the clipboard as «class RTF » à la fois dans l'éditeur script ou en utilisant osascript soutenir cette supposition.

Voici le même Hello World! en texte riche sur le presse-papiers en hexadécimal :

7B5C727466315C616E73695C616E7369637067313235325C636F636F61727466313138375C636F636F617375627274663430300A7B5C666F6E7474626C5C66305C666E696C5C66636861727365743020436F6D696353616E734D533B7D0A7B5C636F6C6F7274626C3B5C7265643235355C677265656E3235355C626C75653235353B7D0A5C706172645C74783732305C7478313434305C7478323136305C7478323838305C7478333630305C7478343332305C7478353034305C7478353736305C7478363438305C7478373230305C7478373932305C7478383634305C7061726469726E61747572616C0A0A5C66305C625C66733336205C6366302048656C6C6F20576F726C64217D

Cependant, ce qui est renvoyé par get the clipboard as «class RTF » pour le Hello World! L'exemple ci-dessus est :

«data RTF 7B5C727466315C616E73695C616E7369637067313235325C636F636F61727466313138375C636F636F617375627274663430300A7B5C666F6E7474626C5C66305C666E696C5C66636861727365743020436F6D696353616E734D533B7D0A7B5C636F6C6F7274626C3B5C7265643235355C677265656E3235355C626C75653235353B7D0A5C706172645C74783732305C7478313434305C7478323136305C7478323838305C7478333630305C7478343332305C7478353034305C7478353736305C7478363438305C7478373230305C7478373932305C7478383634305C7061726469726E61747572616C0A0A5C66305C625C66733336205C6366302048656C6C6F20576F726C64217D»

La chaîne codée en hexadécimal est dans un «data RTF » emballage qui doit être supprimé avant de convertir le contenu codé en hexadécimal en texte ASCII pour être écrit dans un fichier disque en utilisant la redirection des E/S, par exemple. > dans le do shell script commande exemple ci-dessus.

Ainsi, la sortie de osascript -e 'try' -e ' get the clipboard as «class RTF »' -e 'end try' est acheminé ( | ) à awk où il crée une sous-chaîne, n'imprimant que le contenu codé en hexadécimal lui-même, et non l'élément enveloppe de données car elle ne serait pas traitée correctement par les services de l'UE. xxd à l'étape suivante du processus.

Il doit ensuite être acheminé ( | ) à xxd pour la conversion en ASCII Text pour être écrit dans un fichier disque en utilisant la redirection des E/S, par exemple > à la cible chemin, nom de fichier .

L'image ci-dessous est celle de Visionneuse de presse-papiers basculer entre les vues d'encodage ASCII Texte et Hex, montrer Hello World! copié à partir d'un Rich Text Document, celui utilisé dans cet exemple.

Clipboard Viewer


J'espère que cela vous permettra de mieux comprendre comment AppleScript fonctionne avec du contenu Rich Text dans le presse-papiers, car dans tous les cas, la conversion d'une chaîne codée en hexadécimal en texte ASCII doit avoir lieu et cela est fait de manière transparente dans l'exemple original. code tout en nécessitant un traitement supplémentaire en dehors d'AppleScript code en cours de traitement par osascript lorsque vous utilisez le do shell script commande dans ce contexte.

1voto

owlswipe Points 5682

Les fichiers RTF, contrairement aux fichiers TXT, ne sont pas simplement du texte brut mais possèdent une structure de base. Pour créer un fichier RTF, utilisez la structure suivante (au lieu du simple texte brut de votre clavier) :

{\rtf1\ansi\deff0 {\fonttbl {\f0 Verdana;}}
\f0\fs16
Hello World!
}

Source : https://www.safaribooksonline.com/library/view/rtf-pocket-guide/9781449302047/ch01.html

0voto

nisetama Points 894

Voici des fonctions basées sur la réponse de l'utilisateur3439894 pour imprimer la version texte riche du presse-papiers convertie en HTML ou la version HTML du presse-papiers. La version HTML du presse-papiers est incluse pour le texte copié depuis une vue web.

ppr(){ osascript -e'the clipboard as"RTF "'|sed 's/«data RTF //;s/»//'|xxd -r -p|textutil -convert html -stdin -stdout; }

pph(){ osascript -e'the clipboard as"HTML"'|sed 's/«data HTML//;s/»//'|xxd -r -p; }

Le site sed Les commandes ci-dessus peuvent également être remplacées par ruby -lpe'$_=$_[10..-2]' (même si cela sélectionne les mauvaises positions d'octets dans la locale C).

Dans les anciennes versions d'OS X pbpaste -Prefer rtf J'ai imprimé la version RTF du presse-papiers mais maintenant il semble qu'il n'imprime que du texte brut.

LesApples.com

LesApples est une communauté de Apple où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres utilisateurs d'appareils Apple, poser vos propres questions ou résoudre celles des autres.

Powered by:

X