Come utilizzare AppleScript per creare un nuovo file in formato Rich Text dal testo degli Appunti?


5

Ho un servizio di automatore che prende il testo corrente negli appunti e lo scrive in un nuovo file .txt. Questo viene eseguito semplicemente con il seguente pezzo di codice AppleScript:

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

Questo codice proviene dalla seguente risposta di overflow dello stack:

AppleScript per incollare il testo dagli Appunti in un file

Tuttavia, questo codice converte il contenuto degli appunti in testo semplice, rimuovendo tutta la formattazione del testo.

È possibile utilizzare AppleScript per scrivere il contenuto degli appunti in un file .rtf o .rtfd, preservando la formattazione originale del contenuto degli appunti? Con la formattazione originale, mi riferisco a dati stilistici come enfasi tipografica (grassetto, corsivo, sottolineato), dimensione del carattere e colore del testo.

Per un capriccio, ho provato il seguente comando:

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

Ma questo comando ha portato a un file .rtf che il mio computer non è stato in grado di leggere o aprire.


Ho aggiornato la mia risposta per lavorare con il contenuto degli Appunti RTF e HTML.
user3439894,

La mia risposta aggiornata ha funzionato per te?
user3439894,

Risposte:


8

Questa risposta è stata aggiornata per riflettere l' incomprensione della sfera di rubik tra ciò che Rich Text è (ciò che è stato originariamente chiesto) e ciò che viene effettivamente lavorato da Google Chrome, essendo HTML. (Vedi i commenti spostati nella chat .)

Lascio la risposta originale così com'è e sotto questo nuovo contenuto, poiché risponde tecnicamente alla domanda originale come è stata posta. Contiene inoltre informazioni pertinenti al processo complessivo di gestione del contenuto degli Appunti nel contesto della domanda originale e modificata.

Il codice seguente è un esempio di codice da testare ed eseguire all'interno di (Apple) Script Editor, a parte la prima frase nella domanda, non è stato ancora fornito alcun uso esplicito e specifico all'interno di Automator. Il codice può avere bisogno di essere modificato per lavorare all'interno l'utilizzo sconosciuto in Automator. Detto questo, come scritto, se l'intero script qui sotto è stato inserito da solo in un'azione Esegui AppleScript, da solo, in Automator ... funziona così com'è. Se si utilizzano solo segmenti del codice , potrebbe essere necessario apportare alcune modifiche al codice esistente .

Il codice seguente contiene commenti sufficienti per capire in generale cosa sta facendo lo script .


--        # 
--        # 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

Risposta originale alla domanda originale posta:

Per ottenere contenuto Rich Text dagli Appunti in un file usando AppleScript , è un po 'più complesso di un semplice comando .do shell script

Il seguente codice AppleScript di esempio , se il file di destinazione non esiste già e se negli Appunti esiste un contenuto Rich Text , lo scriverà in un file . Avrà tutti gli attributi come ha il contenuto RichText negli Appunti , come ha fatto quando è stato copiato negli Appunti .

Apri Script Editor e copia e incolla il codice seguente in un nuovo documento senza titolo , quindi eseguilo da Script Editor , rivedendo l' output in Eventi / Risposte . Eseguilo un paio di volte, con e senza contenuto Rich Text negli Appunti e con e senza l'esistenza del file , sul disco rigido, definito all'inizio dello script .set theRichTextFileName ...

Vedrai il codice assicurarti che il file non esista, in modo da non sovrascrivere un file esistente del nome e della posizione di destinazione e se gli Appunti non contengono contenuto Rich Text , visualizzerà anche un messaggio per quello.

Ora, se lo si utilizza in un servizio di automazione , ad esempio, dove il servizio riceve il testo RTF selezionato , il codice può essere modificato per non intercettare un errore se il contenuto di Rich Text non è negli Appunti poiché il servizio non verrà visualizzato nel menu Servizi se Rich Text non è selezionato in un documento. Inoltre, se si desidera sovrascrivere il file di destinazione nella posizione designata, è possibile rimuovere anche il codice circostante. Darò anche quegli esempi di codice .


Codice di esempio da incollare in Script Editor per il test e la revisione:

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

Codice di esempio da utilizzare in un servizio di automazione , ad es. Dove il servizio riceve il rich text selezionato :

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

Codice di esempio da utilizzare in un servizio di automazione , ad es. Dove il servizio riceve il testo RTF selezionato e sovrascrive il file di destinazione esistente :

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'immagine qui sotto è un esempio di Automator servizio che crea la nuova RichText Filename.rtf di file da selezionato Rich Text dal Rich Text File Crea da Appunti di servizio sul menu Servizi contestuale (tasto destro del mouse) o Application_name > Servizi > menù , quando Rich Text è selezionato in un documento.

Automator Service - Crea file Rich Text dagli Appunti


Ora questi sono solo esempi e la logica aggiuntiva può essere codificata per adattarla alle proprie esigenze. Ad esempio, è possibile aggiungere un codice per incrementare automaticamente il nome di un file esistente in modo da non sovrascriverlo o richiedere un nuovo nome di file e completare l'operazione anziché interrompere con un messaggio che il file esiste già, ecc.


Aggiornamento da utilizzare con un do shell script comando :

Se vuoi davvero farlo usando un do shell script comando , usa il seguente codice durante la sostituzione /path/to/new rich text file.rtfcon un nome file percorso valido in una posizione in cui hai i permessi di scrittura. Nota di non rimuovere il \"prima e il dopo /path/to/new rich text file.rtfnel comando effettivo poiché gestisce il nome file del percorso se contiene spazi. Se il nome file del percorso non contiene spazi, non è necessario utilizzare \"prima e dopo /path/to/new rich text file.rtf.

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\""

Ecco la riga di comando che mostra come testo a capo, per una visualizzazione più semplice:

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\""

  • Mentre si può copiare e incollare (raccomandare) il codice , tuttavia ecco come digitare le virgolette a doppio angolo, che sono disponibili anche tra parentesi in caratteri (speciali), ad esempio optioncommandTin TextEdit.

    Nota: tenere presente che la spaziatura in «class RTF »deve essere compensata in questo caso d'uso.

    • Scrivere virgolette doppie

      • «Virgolette doppie a sinistra, premere: option\
      • »Virgolette doppie a destra, premere: shiftoption\

Si noti che, come scritto, questo do shell script comando sovrascrive il file di output se esiste già, senza richiedere! Sarà un file di lunghezza zero se gli Appunti non contengono alcun contenuto Rich Text, altrimenti il ​​file avrà la lunghezza necessaria per contenere il contenuto Rich Text dagli Appunti. Ovviamente, la logica aggiuntiva potrebbe essere codificata nel osascript comando, tuttavia se hai bisogno di più complessità, allora è meglio usare il metodo presentato per la prima volta in questa risposta. O usando uno script esterno chiamato da un do shell script comando che gestisce tutta la logica necessaria e la gestione degli errori in base alla complessità delle condizioni generali in cui questo verrà applicato.

  • Perché tale complessità vs do shell script "pbpaste > /path/to/clipboard-file.rtf"?

Questa è una buona domanda e sebbene pbpasteabbia l' -Prefer {txt | rtf | ps}opzione, tuttavia pbpaste -Prefer rtfpotrebbe non produrre Rich Text anche se esiste negli Appunti. O ciò che genera, se non il testo ASCII, non sarà una forma di Rich Text, ad esempio TextEdit, o conterrà tutti gli attributi Rich Text eventualmente presenti nel contenuto degli Appunti.

Ciò rende necessario ottenere il contenuto Rich Text negli Appunti in un modo diverso e perché get the clipboard as «class RTF »viene invece utilizzato. Quando si utilizza un do shell script comando con questo, richiede un'ulteriore elaborazione per utilizzare i dati restituiti, poiché si trova in un wrapper di dati quando restituito e non immediatamente utilizzabile, quindi richiede un'ulteriore elaborazione.

Ad esempio, Hello World!in Rich Text negli Appunti può apparire così in ASCII Text:

{\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!}

Il formato sopra purtroppo non è facilmente utilizzabile, se non del tutto, in AppleScript e credo sia per questo che è necessario essere afferrati come dati codificati Hex .

  • Sto basando questo sul fatto che sebbene il get clipboard info comando per il contenuto degli Appunti in questo esempio ritorni {«class RTF », 265}tra le informazioni restituite, tuttavia mentre la forma di testo ASCII di questo contenuto Rich Text è lunga 265 byte, viene restituita in formato esadecimale oltre due volte i byte con il wrapper di dati . Il fatto che sia restituito in esadecimale get the clipboard as «class RTF »sia dall'editor di script che dall'uso osascriptsupporta questa supposizione.

Ecco lo stesso Hello World!in Rich Text negli Appunti in esadecimale:

7B5C727466315C616E73695C616E7369637067313235325C636F636F61727466313138375C636F636F617375627274663430300A7B5C666F6E7474626C5C66305C666E696C5C66636861727365743020436F6D696353616E734D533B7D0A7B5C636F6C6F7274626C3B5C7265643235355C677265656E3235355C626C75653235353B7D0A5C706172645C74783732305C7478313434305C7478323136305C7478323838305C7478333630305C7478343332305C7478353034305C7478353736305C7478363438305C7478373230305C7478373932305C7478383634305C7061726469726E61747572616C0A0A5C66305C625C66733336205C6366302048656C6C6F20576F726C64217D

Tuttavia, ciò che viene restituito get the clipboard as «class RTF »per l' Hello World!esempio sopra è:

«data RTF 7B5C727466315C616E73695C616E7369637067313235325C636F636F61727466313138375C636F636F617375627274663430300A7B5C666F6E7474626C5C66305C666E696C5C66636861727365743020436F6D696353616E734D533B7D0A7B5C636F6C6F7274626C3B5C7265643235355C677265656E3235355C626C75653235353B7D0A5C706172645C74783732305C7478313434305C7478323136305C7478323838305C7478333630305C7478343332305C7478353034305C7478353736305C7478363438305C7478373230305C7478373932305C7478383634305C7061726469726E61747572616C0A0A5C66305C625C66733336205C6366302048656C6C6F20576F726C64217D»

La stringa con codifica esadecimale si trova in un «data RTF » wrapper che deve essere rimosso prima di convertire il contenuto con codifica esadecimale in testo ASCII da scrivere in un file su disco mediante il reindirizzamento I / O, ad esempio >nell'esempio di do shell script comando sopra.

Quindi, l'output di osascript -e 'try' -e ' get the clipboard as «class RTF »' -e 'end try'viene reindirizzato ( |) a awkdove crea una sottostringa, stampando solo il contenuto codificato Hex stesso, non la parte del wrapper di dati , poiché non verrebbe elaborato correttamente xxdnel passaggio successivo del processo.

Deve quindi essere reindirizzato ( |) a xxdaffinché la conversione ASCII Textvenga scritta in un file su disco utilizzando il reindirizzamento I / O, ad es . Sul nome file del percorso di> destinazione .

L'immagine seguente mostra il Visualizzatore degli Appunti che alterna tra le visualizzazioni di codifica ASCII Text e Hex, mostrata Hello World!copiata da un documento Rich Text, quello usato in questo esempio.

Visualizzatore di appunti


Spero che ciò fornisca una migliore comprensione di come funziona AppleScript con il contenuto Rich Text negli Appunti, poiché deve avvenire la conversione da una stringa codificata Hex in testo ASCII e questo viene fatto in modo trasparente nel codice di esempio originale mentre richiede un'ulteriore elaborazione al di fuori del codice AppleScript in fase di elaborazione osascriptquando si utilizza il do shell script comando in questo contesto.


I commenti non sono per una discussione estesa; questa conversazione è stata spostata in chat .
Nohillside

Sfera di @ rubik, questo codice aveva lo stesso bug dell'altra domanda in quanto il file di destinazione veniva sovrascritto internamente e non cancellato. Ho corretto il bug con l'aggiunta delete the file (theRichTextFileName as POSIX file)all'interno di un Finder tell blocco nel aggiunto altro ramo della if the button returned of the result is "No" then dichiarazione .
user3439894

@la sfera di rubik, per quanto riguarda la modifica che hai richiesto, dovrò rivedere il codice e vedere cosa si può fare, tuttavia poiché questa risposta, ora come è, in realtà risponde alla domanda originale, penso che ogni modifica dovrebbe essere tentato prima da te e poi pubblicato come domanda separata se non riesci a raggiungere il tuo obiettivo. IMO Non è esattamente corretto tornare mesi dopo chiedendo di apportare modifiche a una risposta già accettata e votata che aggiunge ulteriori parametri precedentemente non richiesti alla domanda originale.
user3439894

Chiedo scusa. Hai ragione. Creerò una nuova domanda.
Sfera di Rubik,

Ho capito come aggiungere righe vuote al file quando ho un blocco per appunti di testo semplice e quindi un file .txt, ma non sono riuscito a capire come farlo con un blocco per appunti HTML o RTF. Ecco quella domanda.
Sfera di Rubik

1

I file RTF, a differenza dei file TXT, non sono solo testo normale ma hanno una struttura di base. Per creare un file RTF, utilizzare la seguente struttura (anziché solo il semplice testo della tastiera):

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

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


Ho modificato la mia domanda in modo che sia più chiara. Hai idea di come posso incollare il testo degli Appunti nel file RTF e che il file RTF corrisponda al carattere, alle dimensioni, al colore, ecc. Del testo degli Appunti?
sfera di rubik,

Abbastanza sicuro quello che sta dicendo è che se metti quei metadati in un semplice file di testo e dai l'estensione .rtf, allora hai un file .rtf valido.
Toadfish

@JonathanWarner Lo sono davvero.
civetta pulire il

@ rubik'ssphere Basta sostituire Hello World con il testo degli Appunti e creare il file, il carattere del testo copiato dovrebbe sovrascrivere il predefinito lì di Verdana.
owlswipe,

@John Ramos, Nel tuo commento hai detto `... Sono davvero" al commento di JonathanWarner, tuttavia, come viene scritta la tua risposta, che in realtà non è implicita bene, tanto meno non fornisce alcun esempio pratico di come applicarla in codice formato, che sarebbe stata una risposta migliore di quanto non fosse e nessuna ambiguità su ciò che intendevi. Tuttavia, la sfera di Rubik non vuole prendere il semplice testo dagli appunti e renderlo ricco, vuole il ricco testo che è lì, scritto in un file su disco in modo che mantenga tutti gli attributi rich text che già possiede, non quelli che dovresti codificare manualmente per utilizzare la tua risposta
user3439894

0

Ecco le funzioni basate sulla risposta dell'utente3439894 per stampare la versione rich text degli appunti convertita in HTML o la versione HTML degli appunti. La versione HTML degli Appunti è inclusa per il testo copiato da una vista 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; }

I sedcomandi sopra possono anche essere sostituiti con ruby -lpe'$_=$_[10..-2]'(anche se seleziona le posizioni errate dei byte nella locale C).

Nelle versioni precedenti di OS X pbpaste -Prefer rtfstampava la versione RTF degli appunti, ma ora sembra solo stampare il testo normale.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.