Pano metninden yeni bir Zengin Metin Biçimi dosyası oluşturmak için AppleScript nasıl kullanılır?


5

Panodaki geçerli metni alan ve yeni bir .txt dosyasına yazan bir Otomator Hizmetine sahibim. Bu sadece aşağıdaki AppleScript kodunun parçası ile yürütülür:

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

Bu kod aşağıdaki Yığın Taşması cevabından alınmıştır:

Panodan bir dosyaya metin yapıştırmak için AppleScript

Ancak, bu kod pano içeriğini düz metne dönüştürerek metnin tüm formatını kaldırır.

Pano içeriğinin orijinal biçimini korurken, pano içeriğini bir .rtf veya .rtfd dosyasına yazmak için AppleScript kullanmak mümkün müdür? Orijinal biçimlendirme ile, tipografik vurgu (kalın, italik, altı çizili), yazı tipi boyutu ve metin rengi gibi stilistik verilere atıfta bulunuyorum.

Bir hevesle aşağıdaki komutu denedim:

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

Ancak bu komut, bilgisayarımın okuyamadığı veya açamadığı bir .rtf dosyasıyla sonuçlandı.


Cevabımı hem RTF hem de HTML Pano içeriği ile çalışmak üzere güncelledim.
user3439894 14:16

Güncellenmiş cevabım sizin için işe yaradı mı?
user3439894 18:16

Yanıtlar:


8

Bu cevap, Rubik'in kürenin Zengin Metin'in ne olduğu (başlangıçta sorulanlar) ile gerçekte Google Chrome'dan neyin üzerinde çalıştığı ile HTML arasındaki yanlış anlaşılmayı yansıtacak şekilde güncellenmiştir . ( Sohbete taşınan yorumları görün .)

Asıl cevabı olduğu gibi bırakıyorum ve bu yeni içeriğin altında, asıl soruyu teknik olarak sorduğu gibi yanıtlıyor. Ayrıca, orijinal ve değiştirilmiş soru bağlamında Pano içeriğiyle ilgili genel işlem süreciyle ilgili bilgileri de içerir.

Aşağıdaki kod , söz konusu ilk cümlenin yanı sıra, (Apple) Komut Dosyası Düzenleyicisi içinde test edilecek ve çalıştırılacak örnek koddur , henüz Automator içinde açık ve özel bir kullanım yapılmamıştır. Kod Automator'ın bilinmeyen kullanım içinde çalışmaya düzenlenebilir gerekebilir. Bununla birlikte, yazıldığı gibi, aşağıdaki komut dosyasının tamamı kendi başına bir AppleScript Çalıştır eylemine yerleştirildiyse, kendi başına, Automator'da ... olduğu gibi çalışır. Kodun yalnızca bölümlerini kullanıyorsanız , mevcut kodda bazı değişiklikler yapılması gerekebilir.

Aşağıdaki kod , betiğin ne yaptığını genel olarak anlamak için yeterli yorum içeriyor .


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

Asıl sorunun cevabını sordum:

Almak için zengin metin içeriği dan panoya bir içine dosyası kullanarak AppleScript , basit bir sonra biraz daha karmaşık do shell script komut .

Örnek AppleScript kod aşağıda, hedef eğer edecektir dosya zaten yok ve eğer zengin metin içeriği üzerinde var panoya , bir bölümüne yazarlar dosyası . Her şey olacaktır özelliklerini olarak RichText içerik üzerinde panoya sahip kopyalanan zaman yaptığı gibi, panoya .

Komut Dosyası Düzenleyicisi'ni açın ve aşağıdaki kodu kopyalayıp yeni bir Adsız belgeye yapıştırın ve ardından Çıktıyı Olaylar / Yanıtlar bölümünde inceleyerek Komut Dosyası Düzenleyicisi'nden çalıştırın . O olan ve olmayan birkaç kez, Run Zengin Metin içeriği üzerinde Panoya ile ve varlığı olmadan dosyasında tanımlanan sabit diskte, başlangıcında senaryo . set theRichTextFileName ...

Göreceksin kod emin olur dosyası bir çıkarken üzerine etmemek için, yoksa dosyayı hedef adı ve konumu ve eğer Pano içermiyor Zengin Metin içeriği , çok bunun için bir mesaj gösterir.

Bir in bu kullanılıyorsa Şimdi Otomatikçisi Servisi örneğin Servisi zengin metin seçilmiş aldığı , daha sonra kod eğer bir hata için tuzak değil değiştirilebilir zengin metin içeriği üzerinde değil panoya olarak hizmet görünmez Servisler menüsünde ise Bir belgede Zengin Metin seçilmemiş. Ayrıca, hedef dosyanın belirtilen yerinde üzerine yazmak isterseniz, çevresindeki kod da kaldırılabilir. Ben de bu kod örneklerini vereceğim .


Test ve inceleme için Kod Düzenleyicisine yapıştırılacak örnek kod :

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

Bir Automator Hizmetinde kullanılacak örnek kod , örneğin, Servisin seçili zengin metni aldığı yer :

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

Bir Automator Hizmetinde kullanılacak örnek kod ; örneğin, Servis seçilen zengin metni alır ve mevcut hedef dosyanın üzerine yazar :

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

Aşağıdaki resimde bir örnek olduğunu Otomatikleştirici Servisi oluşturur Yeni RichText Filename.rtf dosyası seçilen dan Zengin Metin dan Pano Oluştur Zengin Metin dosyası hizmeti üzerinde Servisler Bağlam menüsü (sağ tıklama ile) ya da APPLICATION_NAME > Hizmetler > menü , ne zaman Bir belgede Zengin Metin seçili.

Automator Service - Panodan Zengin Metin dosyası oluşturun


Şimdi bunlar sadece örneklerdir ve ihtiyaçlarını karşılamak için ek bir mantık kodlanabilir. Bir örnek olarak, kod otomatik üzerine yazmak etmemek için varolan dosyanın adına artırmak veya yeni bir dosya adı için istemde vb dosya zaten var olan bir mesajla birlikte iptal vs işlemi tamamlamak için eklenebilir


Bir do shell script komutla kullanım için güncelleme :

Eğer gerçekten bir kullanarak yapmak istiyorsanız do shell script komutu , ardından aşağıdaki kullanmak kod değiştirirken /path/to/new rich text file.rtfgeçerli olan yol dosya yazma izinlerine sahip bir konuma. Asıl komutta\" önceki ve sonrasını kaldırmamaya dikkat edin /path/to/new rich text file.rtf, çünkü boşluk içeriyorsa yol dosya adını işler . Eğer yol dosyaadı boşluk içermediğinden, daha sonra önce ve sonra kullanılmak üzere ihtiyaç duymaz.\"/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\""

İşte daha kolay görebilmek için kaydırılmış metin olarak gösterilen komut satırı

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

  • Biri kodu kopyalayıp yapıştırabilir (tavsiye edebilir) olsa da , burada ayrıca (Özel) Karakterler içindeki Parantez altında da bulunan (örneğin optioncommandT, TextEdit'deki ) Çift Açılı Tırnak İşaretlerini nasıl yazacağınızı görebilirsiniz.

    Not: «class RTF »Bu kullanım durumunda aradaki mesafenin dengelenmesi gerektiğini unutmayın .

    • Çift açılı tırnak işaretleri yazarak

      • «Sol Çift Açılı Tırnak İşareti, şu tuşa basın: option\
      • »Sağ Çift Açılı Tırnak işareti, şu tuşa basın: shiftoption\

Bu do shell script komutun yazıldığı gibi, istenmeden çıktı dosyasının üzerine yazdığını unutmayın ! Eğer Pano herhangi bir Zengin Metin içeriği içermiyorsa, sıfır uzunluklu bir dosya olacaktır, aksi takdirde dosya Zengin Metin içeriğini Panodan içerecek şekilde gerekli uzunlukta olacaktır. Açıkçası, ek bir mantık osascript komuta kodlanmış olabilir, ancak daha fazla karmaşıklığa ihtiyaç duyarsanız, bu cevapta ilk önce sunulan yöntemi kullanarak daha iyi olursunuz. Veya uygulanacak genel koşulların karmaşıklığına dayalı olarak gerekli tüm mantığı ve hata işlemeyi yapan do shell script komutla çağrılan harici bir komut dosyası kullanarak .

  • Neden böyle karmaşıklık vs do shell script "pbpaste > /path/to/clipboard-file.rtf"?

Bu iyi bir soru ve seçeneğe pbpastesahip olsa da -Prefer {txt | rtf | ps}, Pano'da pbpaste -Prefer rtfolsa bile Zengin Metin çıktısı almayabilir. Ya da ASCII Metin olmasa da çıktıları, örneğin TextEdit tarafından anlaşılan bir Zengin Metin biçimi olmayacak ve Pano içeriğinin içerdiği tüm Zengin Metin niteliklerini içermeyecek ya da içermeyecektir .

Bu, Zengin Metin içeriğinin Pano'da farklı bir şekilde alınmasını ve bunun neden get the clipboard as «class RTF »kullanıldığını gerekli kılar . Bununla bir do shell script komut kullanılırken, döndürülen verileri kullanmak için ek işlem yapılmasını gerektirir , çünkü iade edildiğinde bir veri paketinde olduğundan ve hemen kullanılamazsa, bu nedenle daha fazla işlem yapılmasını gerektirir.

Örnek olarak, Hello World!Panodaki Zengin Metin içindeki ASCII Metin'deki gibi görünebilir:

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

Yukarıdaki format ne yazık ki AppleScript'te kolayca kullanılamıyor ve Hex kodlu veri olarak alınmasının gerekmediğine inanıyorum .

  • Bunu , bu örnekteki Pano içeriğine ilişkin get clipboard info komutun , {«class RTF », 265}geri gönderilen bilgiler arasında döndürmesine rağmen, yine de, bu Zengin Metin içeriğinin ASCII Metin biçimi 265 bayt uzunluğunda iken, Hex biçiminde iki defadan fazla döndürüldüğünü temel alır. veri paketleyicisine sahip bayt sayısı . get the clipboard as «class RTF »Hem Kod Düzenleyicisi'nde hem de bu yöntem kullanılarak Hex'te döndürülmüş olması osascript.

İşte Hello World!Onaltılı Panodaki Zengin Metin'de aynı :

7B5C727466315C616E73695C616E7369637067313235325C636F636F61727466313138375C636F636F617375627274663430300A7B5C666F6E7474626C5C66305C666E696C5C66636861727365743020436F6D696353616E734D533B7D0A7B5C636F6C6F7274626C3B5C7265643235355C677265656E3235355C626C75653235353B7D0A5C706172645C74783732305C7478313434305C7478323136305C7478323838305C7478333630305C7478343332305C7478353034305C7478353736305C7478363438305C7478373230305C7478373932305C7478383634305C7061726469726E61747572616C0A0A5C66305C625C66733336205C6366302048656C6C6F20576F726C64217D

Bununla birlikte, yukarıdaki örnek get the clipboard as «class RTF »için geri dönen Hello World!şey:

«data RTF 7B5C727466315C616E73695C616E7369637067313235325C636F636F61727466313138375C636F636F617375627274663430300A7B5C666F6E7474626C5C66305C666E696C5C66636861727365743020436F6D696353616E734D533B7D0A7B5C636F6C6F7274626C3B5C7265643235355C677265656E3235355C626C75653235353B7D0A5C706172645C74783732305C7478313434305C7478323136305C7478323838305C7478333630305C7478343332305C7478353034305C7478353736305C7478363438305C7478373230305C7478373932305C7478383634305C7061726469726E61747572616C0A0A5C66305C625C66733336205C6366302048656C6C6F20576F726C64217D»

Hex kodlanmış dize, örneğin yukarıdaki komut örneğinde , G / Ç Yönlendirmesi kullanılarak, Hex kodlanmış içeriği ASCII Metne dönüştürülmeden önce kaldırılması gereken bir «data RTF » sargıda bulunur.>do shell script

Bu nedenle, bir alt-tabaka oluşturduğu yere osascript -e 'try' -e ' get the clipboard as «class RTF »' -e 'end try'piped ( |) , işlemin bir sonraki basamağında doğru bir şekilde işlenmeyeceği gibi awk, veri sarıcı kısmını değil sadece Hex kodlanmış içeriğin kendisini basarxxd .

Daha sonra, dönüştürülmek üzere G / Ç Yönlendirmesi kullanılarak bir disk dosyasına, örneğin hedef yolun dosya adına dönüştürülmek üzere pipolanmalıdır ( |) .xxdASCII Text>

Aşağıdaki resim , bu örnekte kullanılan bir Zengin Metin Belgesinden kopyalandığını gösteren ASCII Metin ve Hex kodlama görünümleri arasında geçiş yapan Pano GörüntüleyicisidirHello World! .

Pano Görüntüleyicisi


Umarım bu, AppleScript’in Pano’daki Zengin Metin içeriğiyle nasıl çalıştığını daha iyi anlayabilmenizi sağlar, çünkü Hex kodlu bir dizgeden ASCII Metin’e dönüşümün yapılması gerekir ve bu, orijinal işlem kodunda şeffaf bir şekilde yapılırken, ek işlem yapılmasını gerektirir. Bu bağlamda komut kullanılırken AppleScript kodunun dışında işleniyor .osascriptdo shell script


Yorumlar uzun tartışmalar için değildir; bu konuşma sohbete taşındı .
nohillside

@ rubik'in alanı, Bu kod diğer sorunuzdaki ile aynı hataya sahipti, çünkü hedef dosyanın dahili olarak silinmemiş olması üzerine yazılmıştır. Ben düzelttim hata ekleyerek delete the file (theRichTextFileName as POSIX file)bir Finder içinde tell blokta eklendi içinde başka dalı arasında if the button returned of the result is "No" then beyanı .
user3439894

@ Rubik küre, sizin için sordunuz değişikliğe gelince, gözden gerekecek kodu ancak bu cevap beri, şimdi olduğu gibi, aslında orijinal soru sorulduğunda cevap ve neler yapılabileceğini görmek için, herhangi bir değişiklik gerektiğini hissediyorum önce tarafınızdan denenmeli ve daha sonra hedefinize ulaşamıyorsanız, ayrı bir soru olarak gönderilmelidir. IMO Aylar sonra geri gelmek tam anlamıyla doğru değil, daha önce kabul edilmemiş ve oylanan bir cevapta, orijinal soruya daha önce sorulmamış parametreler ekleyen değişiklikler yapılması isteniyor.
user3439894

Özür dilerim. Haklısın. Yeni bir soru yaratacağım.
rubik küresi

Düz bir metin panosuna ve böylece .txt dosyasına sahipken dosyaya nasıl boş satırlar ekleneceğini anladım, ancak bir HTML veya RTF panosuyla nasıl yapılacağını çözemedim. İşte bu soru.
rubik'in küre

1

RTF dosyaları, TXT dosyalarının aksine, yalnızca düz metin değildir, temel bir yapıya sahiptir. Bir RTF dosyası oluşturmak için aşağıdaki yapıyı kullanın (klavyenizdeki yalnızca düz metin yerine):

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

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


Sorumu daha net olması için düzenledim. Pano metnini RTF dosyasına nasıl yapıştırabileceğime ve RTF dosyasının pano metninin yazı tipi, boyutu, rengi vb. İle eşleşmesine dair bir fikrim var mı?
rubik'in küresi

Söylediğinden eminim, eğer meta verileri düz bir metin dosyasına koyarsanız ve .rtf uzantısını verirseniz, geçerli bir .rtf dosyanız olur.
Toadfish

@JonathanWarner Ben gerçekten.
owlswipe

@ rubik'ssphere Sadece Hello World’ü panodaki metninizle değiştirin ve dosyayı oluşturun, kopyalanan metnin fontu, varsayılan olarak Verdana’nın yerine geçmelidir.
owlswipe

@John Ramos, Yorumunuzda “… Ben gerçekten” dedim, ancak JonathanWarner'ın yorumuna, cevabınız nasıl yazılır, bu gerçekten iyi bir şekilde ima edilmez, kodlanmış olarak nasıl uygulanacağı konusunda pratik bir örnek vermez daha iyi bir cevap olurdu formatı, öyleydi ve ne demek istediğiyle ilgili bir belirsizlik yoktu.Ama rubik'in alanı panodan düz metin almak ve zengin metin yapmak istemiyor, orada bulunan zengin metni istiyor bir disk dosyasına, zaten sahip olduğu tüm zengin metin özelliklerini korur, cevabınızı kullanmak için manuel olarak kodlamanız gerekecek olanları değil
user3439894

0

İşte, kullanıcının3439894 tarafından verilen cevaba göre, panonun zengin metin sürümünü HTML'ye veya panonun HTML sürümünü yazdırmak için kullandığı işlevler. Panodaki HTML sürümü web görünümünden kopyalanan metinler için dahil edilmiştir.

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; }

Yukarıdaki sedkomutlar ile de değiştirilebilir ruby -lpe'$_=$_[10..-2]'(C yerel ayarında yanlış bayt konumlarını seçmesine rağmen).

OS X'in eski sürümlerinde pbpaste -Prefer rtf, panonun RTF sürümünü yazdırdı, ancak şimdi düz metin yazdırıyor gibi görünüyor.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.