Come scrivere testo in un file RTF, mantenendo lo stile di un modello di documento, in AppleScript?

1

Ho un codice AppleScript che sto riscontrando problemi nella scrittura.

Vorrei un nuovo file .rtf vuoto da creare con un nome file definito dall'utente, salvato in una posizione predeterminata, con un modello di documento predeterminato. So già come realizzare tutte queste funzioni in AppleScript.

Mi piacerebbe quindi che il testo normale negli appunti fosse scritto sul documento e il testo semplice per corrispondere allo stile del modello di documento predeterminato. È questo desiderio che crea difficoltà.

Se gli appunti contengono una formattazione (come lo stile del carattere, la dimensione del carattere, lo stile enfatizzato, il colore del testo o il colore di evidenziazione), vorrei che queste informazioni fossero ignorate e invece il testo degli Appunti corrispondesse alla formattazione predeterminata dell'RTF file.

Ecco il codice che ho a questo punto. Sentiti libero di abbandonare il mio approccio, dato che non riesco a farlo funzionare.

(Il seguente codice AppleScript è quasi identico a questo codice da parte dell'utente3439894 . Ho contrassegnato il mio (errato ) aggiunte introducendo righe di codice che ho scritto io stesso con "Il mio nuovo codice".)

global theCustomRichTextFilePathname
global customFilename
global fullDataToWriteToRTFfile




repeat
    set customFilename to the text returned of (display dialog "Save as:" with title "Do you want to create a new, blank TextEdit RTF document?" default answer "")
    if customFilename is "" then
        beep
        display alert "The filename cannot be empty!" message "Please enter a name to continue..."
    else
        exit repeat
    end if
end repeat


set theCustomRichTextFilePathname to ((path to desktop) & customFilename & ".rtf") as string




-- My new code:

set hexOfTheClipboardText to convertATextStringToItsHexFormat()

set hexOfTheClipboardText to (hexOfTheClipboardText & "7D")
-- The 7D in the above line represents the hex code of the closing bracket } that must be the last character of the RTF data string.

set dataForTheRTFDocumentTemplateThatIWant to "7B5C727466315C616E73695C616E7369637067313235325C636F636F61727466313430345C636F636F617375627274663437300A7B5C666F6E7474626C5C66305C6673776973735C6663686172736574302048656C7665746963613B7D0A7B5C636F6C6F7274626C3B5C7265643235355C677265656E3235355C626C75653235353B7D0A5C6D6172676C313434305C6D61726772313434305C766965777731303830305C7669657768383430305C766965776B696E64300A5C706172645C74783732305C7478313434305C7478323136305C7478323838305C7478333630305C7478343332305C7478353034305C7478353736305C7478363438305C7478373230305C7478373932305C7478383634305C7061726469726E61747572616C5C7061727469676874656E666163746F72300A0A5C66305C66733336205C636630205C0A"

set fullDataToWriteToRTFfile to (dataForTheRTFDocumentTemplateThatIWant & hexOfTheClipboardText)


-- End of my new code.




tell application "Finder"
    try
        if exists file theCustomRichTextFilePathname then
            tell current application
                display dialog "The file \"" & POSIX path of theCustomRichTextFilePathname & "\" already exists!" & return & return & "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 result is "No" then
                    --  # The file already exists, chose not to overwrite it, just open the document.
                    my openDocument()
                else
                    --  # The file already exists, chose to overwrite it, then open the document.
                    my createCustomRTFDocument()
                    my openDocument()
                end if
            end tell
        else
            --  # The file does not already exist. Create and open the document.
            tell current application
                my createCustomRTFDocument()
                my openDocument()
            end tell
        end if
    on error eStr number eNum
        activate
        display dialog eStr & " number " & eNum buttons {"OK"} default button 1 with icon caution
        return
    end try
end tell







on createCustomRTFDocument()
    tell current application

         -- My new line of code:
        set customRTFDocumentTemplate to «data RTF fullDataToWriteToRTFfile»
         -- THE ABOVE LINE DOES NOT WORK AND SENDS AN ERROR.



            try
                set referenceNumber to open for access theCustomRichTextFilePathname with write permission
                write customRTFDocumentTemplate to referenceNumber
                close access referenceNumber
            on error eStr number eNum
                activate
                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
        end tell
    end createCustomRTFDocument






on openDocument()
    try
        tell application "TextEdit"
            open file theCustomRichTextFilePathname
            activate
            tell application "System Events"
                set displayedName to get displayed name of file theCustomRichTextFilePathname
                if displayedName contains ".rtf" then
                    tell application "TextEdit"
                        set bounds of window (customFilename & ".rtf") to {160, 22, 883, 639}
                    end tell
                    key code 125
                else
                    tell application "TextEdit"
                        set bounds of window customFilename to {160, 22, 883, 639}
                    end tell
                    key code 125
                end if
            end tell
        end tell
    on error eStr number eNum
        activate
        display dialog eStr & " number " & eNum buttons {"OK"} default button 1 with icon caution
        return
    end try
end openDocument





-- New code:

on convertATextStringToItsHexFormat()
    set hexOfText to ""
    set letters to every character in the clipboard
    repeat with letter in letters
        set numberRepresentingTheID to (id of letter)
        set hexOfText to hexOfText & list2hex(numberRepresentingTheID)
    end repeat
    return hexOfText
end convertATextStringToItsHexFormat

on list2hex(X)
    set y to ""
    repeat with Z in {} & X
        set y to y & num2hex(Z) & ","
    end repeat
    set y to text 1 thru -2 of y
    return y
end list2hex

on num2hex(X)
    set y to ""
    repeat until X = 0
        set n to X mod 16
        if n > 9 then
            set y to character id (55 + n) & y
        else
            set y to character id (48 + n) & y
        end if
        set X to X div 16
    end repeat
    return y
end num2hex

-- End of new code

So che forse il modo più semplice per ottenere ciò che voglio è semplicemente il tasto di scelta rapida da tastiera per "Incollare e abbinare lo stile" in TextEdit.app, cioè ⌥ opzione + + ⌘ comando + V . Ma speravo in un "back-end" e in un metodo più sofisticato, dal momento che il keystroking porta con sé un ritardo notevole.

    
posta rubik's sphere 07.02.2017 - 21:52
fonte

3 risposte

2

Ecco un altro metodo con un'applet Cocoa-AppleScript, questo script crea il file RTF con i metodi dal codice Obiettivo-C .

-- Cocoa-AppleScript
use framework "Foundation"
use scripting additions
repeat
    set customFilename to the text returned of (display dialog "Save as:" with title "Do you want to create a new, blank TextEdit RTF document?" default answer "")
    if customFilename is "" then
        beep
        display alert "The filename cannot be empty!" message "Please enter a name to continue..."
    else
        exit repeat
    end if
end repeat
set theCustomRichTextFilePathname to ((path to desktop as string) & customFilename & ".rtf")

tell application "Finder" to set b to exists file theCustomRichTextFilePathname
tell current application
    try
        if b then
            display dialog "The file \"" & POSIX path of theCustomRichTextFilePathname & "\" already exists!" & return & return & "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 result is "No" then
                --  # The file already exists, chose not to overwrite it, just open the document.
                my openDocument(theCustomRichTextFilePathname)
                return
            end if
        end if
        -- else, the file already exists, chose to overwrite it or the file does not already exist
        my createCustomRTFDocument(theCustomRichTextFilePathname)
    on error eStr number eNum
        activate
        display dialog eStr & " number " & eNum buttons {"OK"} default button 1 with icon caution
        return
    end try
end tell

on openDocument(f)
    tell application "TextEdit"
        set theDoc to open file f
        set bounds of (first window whose its document is theDoc) to {160, 22, 883, 639}
        activate
    end tell
    tell application "System Events" to key code 125 using command down --put the blinking cursor at the end of the document
end openDocument

on createCustomRTFDocument(f)
    set myText to return & (the clipboard as string) -- Concatenation of an empty line and the text in the clipboard
    set theFile to POSIX path of f
    tell current application
        set myFont to its (NSFont's fontWithName:"Helvetica" |size|:18) -- font and size of the rtf document
        set myColor to its (NSColor's blackColor()) -- color of the text of the rtf document
        set theDict to its (NSDictionary's alloc()'s initWithObjectsAndKeys_(myColor, its NSForegroundColorAttributeName, myFont, its NSFontAttributeName, missing value))
        set AttrString to its ((NSAttributedString's alloc)'s initWithString:myText attributes:theDict) -- create an attributed string
        set rtfData to AttrString's RTFFromRange:{0, AttrString's |length|()} documentAttributes:{NSRTFTextDocumentType:(its NSDocumentTypeDocumentAttribute)} -- create the data from an attributed string
    end tell
    rtfData's writeToFile:theFile atomically:true -- write the data to the RTF file
    if the result then my openDocument(f) -- open the file 
end createCustomRTFDocument
    
risposta data 08.02.2017 - 20:07
fonte
2

Questo script crea un nuovo documento in TextEdit e usa le proprietà del testo per cambiare la formattazione del documento RTF (guarda il gestore createCustomRTFDocument () ):

repeat
    set customFilename to the text returned of (display dialog "Save as:" with title "Do you want to create a new, blank TextEdit RTF document?" default answer "")
    if customFilename is "" then
        beep
        display alert "The filename cannot be empty!" message "Please enter a name to continue..."
    else
        exit repeat
    end if
end repeat
set theCustomRichTextFilePathname to ((path to desktop) & customFilename & ".rtf") as string

tell application "Finder" to set b to exists file theCustomRichTextFilePathname
tell current application
    try
        if b then
            display dialog "The file \"" & POSIX path of theCustomRichTextFilePathname & "\" already exists!" & return & return & "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 result is "No" then
                --  # The file already exists, chose not to overwrite it, just open the document.
                my openDocument(theCustomRichTextFilePathname)
                return
            end if
        end if
        -- else, the file already exists, chose to overwrite it or the file does not already exist
        my createCustomRTFDocument(theCustomRichTextFilePathname)
    on error eStr number eNum
        activate
        display dialog eStr & " number " & eNum buttons {"OK"} default button 1 with icon caution
        return
    end try
end tell

on openDocument(f)
    tell application "TextEdit"
        set theDoc to open file f
        activate
        set bounds of (first window whose its document is theDoc) to {160, 22, 883, 639}
    end tell
    tell application "System Events" to key code 125 using command down -- put the blinking cursor at the end of the document
end openDocument

on createCustomRTFDocument(f)
    close access (open for access f) -- create a blank file , this command do nothing on an existing file
    -- delay 0.5 -- use the delay command, If you have permission issues (you can increase the number of seconds).

    set myText to return & (the clipboard as string) -- Concatenation of an empty line and the text in the clipboard
    set theFile to POSIX path of f
    tell application "TextEdit"
        set theDoc to make new document with properties {path:theFile} -- create new document

        -- this put the text in the document, *** use (font, size and color) properties to set the predetermined formatting of the RTF document *** {0, 0, 0} = black color
        make new attribute run at beginning of theDoc with data myText with properties {font:"Helvetica", size:18, color:{0, 0, 0}} -- this put the blinking cursor at the end of the document

        set bounds of (first window whose its document is theDoc) to {160, 22, 883, 639}
        save theDoc in theFile
        activate
    end tell
end createCustomRTFDocument
    
risposta data 08.02.2017 - 04:45
fonte
2

Questa risposta incorpora il codice esistente della mia risposta che hai inserito nella tua domanda con le seguenti modifiche.

Nel openDocument() gestore , key code 125 è stato modificato in key code 125 using command down in modo da inviare il cursore sull'ultima riga del documento all'apertura.

Il createCustomRTFDocument() gestore ha aggiunto my addPlainTextFromClipboardToEndOfNewelyCreatedRTFDocument() dopo la chiusura del Documento RTF appena creato, essendo stato creato dal Modello. La creazione del documento RTF ora è un processo in due fasi, il primo passaggio crea il documento dal modello, il secondo passaggio aggiunge il testo dagli Appunti come testo semplice, se il testo esiste, che viene eseguito prima che il documento venga aperto per la prima volta Utente dal openDocument() gestore .

Un nuovo gestore è stato creato e denominato addPlainTextFromClipboardToEndOfNewelyCreatedRTFDocument() e codificato per fare esattamente come viene letto il suo nome. Otterrà il testo dagli appunti come testo normale, se esiste, e lo scriverà alla fine del documento RTF appena creato creato dalla prima parte customRTFDocumentTemplate() gestore .

Ho trovato un bug nel mio code originale, il file veniva sovrascritto internamente non cancellando il file e ricreandolo come dovrebbe essere in questo caso. Ho aggiunto codice per correggere quello in questo codice e modificherò l'altra risposta da aggiungere a quel codice . Per tenere conto del bug, ho aggiunto & return & return & "If yes, the file will be placed in the Trash." al "Do you want to overwrite the file?" display dialog comando nel% principaletell application "Finder" blocco . Inoltre, ha aggiunto il seguente codice all'interno della else clausola dell'istruzione if the button returned of result is "No" then per gestire il bug.

tell application "Finder"
    delete the file theCustomRichTextFilePathname
end tell

Anche questo è all'interno del tell application "Finder" blocco primario.

Con le modifiche di cui sopra, ecco il nuovo codice :

--  # The variables for the target file's fully qualified pathname and custom filename needs to be global as they are called from both the handlers and other code.

global theCustomRichTextFilePathname
global customFilename

--  # The createCustomRTFDocument handler contains a custom template for the target RTF document.

on createCustomRTFDocument()
    tell current application
        set customRTFDocumentTemplate to «data RTF 7B5C727466315C616E73695C616E7369637067313235325C636F636F61727466313530345C636F636F617375627274663736300A7B5C666F6E7474626C5C66305C6673776973735C6663686172736574302048656C7665746963613B7D0A7B5C636F6C6F7274626C3B5C7265643235355C677265656E3235355C626C75653235353B7D0A7B5C2A5C657870616E646564636F6C6F7274626C3B3B7D0A5C706172645C74783732305C7478313434305C7478323136305C7478323838305C7478333630305C7478343332305C7478353034305C7478353736305C7478363438305C7478373230305C7478373932305C7478383634305C7061726469726E61747572616C5C7061727469676874656E666163746F72300A0A5C66305C66733336205C636630205C0A7D»
        try
            set referenceNumber to open for access theCustomRichTextFilePathname with write permission
            write customRTFDocumentTemplate to referenceNumber
            close access referenceNumber
            my addPlainTextFromClipboardToEndOfNewelyCreatedRTFDocument()
        on error eStr number eNum
            activate
            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
    end tell
end createCustomRTFDocument

--  # The addPlainTextFromClipboardToEndOfNewelyCreatedRTFDocument handler attemps to get plain text from the clipboard 
--  # and if there is some, it's added to the end of the newely created RTF document created by the customRTFDocumentTemplate 
--  # handler so as to maintain a valid RTF Docuemnt. The addPlainTextFromClipboardToEndOfNewelyCreatedRTFDocument handler
--  # is called from the createCustomRTFDocument handler after it has created the new RTF document from the Template.

on addPlainTextFromClipboardToEndOfNewelyCreatedRTFDocument()
    tell current application
        set plainTextFromClipboard to (get the clipboard as «class utf8»)
        if plainTextFromClipboard is not equal to "" then
            set plainTextFromClipboard to return & plainTextFromClipboard & return & "\
}" as «class utf8»
            try
                tell application "Finder"
                    set eofMinusOne to (size of file theCustomRichTextFilePathname) - 1
                end tell
                set referenceNumber to open for access theCustomRichTextFilePathname with write permission
                write plainTextFromClipboard to referenceNumber starting at eofMinusOne
                close access referenceNumber
            on error eStr number eNum
                activate
                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
        end if
    end tell
end addPlainTextFromClipboardToEndOfNewelyCreatedRTFDocument

--  # The openDocument handler opens and set the bounds of the theCustomRichTextFilePathname document while placing the cursor on the second line.

on openDocument()
    try
        tell application "TextEdit"
            open file theCustomRichTextFilePathname
            activate
            tell application "System Events"
                set displayedName to get displayed name of file theCustomRichTextFilePathname
                if displayedName contains ".rtf" then
                    tell application "TextEdit"
                        set bounds of window (customFilename & ".rtf") to {160, 22, 883, 639}
                    end tell
                    key code 125 using command down
                else
                    tell application "TextEdit"
                        set bounds of window customFilename to {160, 22, 883, 639}
                    end tell
                    key code 125 using command down
                end if
            end tell
        end tell
    on error eStr number eNum
        activate
        display dialog eStr & " number " & eNum buttons {"OK"} default button 1 with icon caution
        return
    end try
end openDocument

--  # Get the name for the RTF document, ensuring it is not blank.

repeat
    set customFilename to the text returned of (display dialog "Save as:" with title "Do you want to create a new, blank TextEdit RTF document?" default answer "")
    if customFilename is "" then
        beep
        display alert "The filename cannot be empty!" message "Please enter a name to continue..."
    else
        exit repeat
    end if
end repeat

--  # Concatenate the default location (the User's Desktop) with the chosen filename while adding the proper file extension.

set theCustomRichTextFilePathname to ((path to desktop) & customFilename & ".rtf") as string

--  # Check to see if the target file already exists. If it does not exist, create and open it. If it does exist, either open it or overwrite it and open it, based on decision made.

tell application "Finder"
    try
        if exists file theCustomRichTextFilePathname then
            tell current application
                display dialog "The file \"" & POSIX path of theCustomRichTextFilePathname & "\" already exists!" & return & return & "Do you want to overwrite the file?" & return & return & "If yes, the file will be placed in the Trash." buttons {"No", "Yes"} default button 1 with title "File Already Exists..." with icon caution
                if the button returned of result is "No" then
                    --  # The file already exists, chose not to overwrite it, just open the document.
                    my openDocument()
                else
                    --  # The file already exists, chose to overwrite it, then open the document.
                    tell application "Finder"
                        delete the file theCustomRichTextFilePathname
                    end tell
                    my createCustomRTFDocument()
                    my openDocument()
                end if
            end tell
        else
            --  # The file does not already exist. Create and open the document.
            tell current application
                my createCustomRTFDocument()
                my openDocument()
            end tell
        end if
    on error eStr number eNum
        activate
        display dialog eStr & " number " & eNum buttons {"OK"} default button 1 with icon caution
        return
    end try
end tell
    
risposta data 08.02.2017 - 05:32
fonte

Leggi altre domande sui tag