Web Smith Web Smith - 27 days ago 9
AppleScript Question

Can I create an Applescript that will paste a web text clip appended with source attribution and a timestamp, while maintaining embedded links?

Complete newbie here so please let me know if I need to clarify or otherwise improve my question.
I have searched multiple times using different keywords and have not been able to find a solution to my issue.

I want to create a script (Applescript) that when triggered will allow me to paste a web text clip appended with source attribution and a timestamp, without loosing any possible embedded links within the selected text.

Here is a screen shot of what I want to achieve:

Not knowing much of anything programming wise, I was able to cobble together the following script (Applescript) after a few days of web searching.

-- clear the clipboard
tell application "Finder"
set the clipboard to " "
delay 0.1
end tell

-- copy selected text
tell application "Safari"
activate
tell application "System Events"
tell process "Safari"
keystroke "c" using {command down}
delay 0.1
end tell
end tell
end tell

-- open and paste web clip into specified TextEdit file
tell application "TextEdit"
activate
open "Macintosh HD:Users:Web:Documents:Web Text Clips:Web_Text_Clips.rtf"
delay 0.2
tell application "System Events"
tell process "TextEdit"
keystroke "v" using {command down}
delay 0.1
end tell
end tell
end tell

-- get, format and copy source info and timestamp
tell application "Safari"
activate
set theLongDate to current date
set theWindowName to the name of the front window
set theURL to the URL of the front document
set writeString to "- - - - - " & return & "From: " & theURL & return & "Page Title: " & theWindowName & return & "Date: " & theLongDate
set the clipboard to writeString
end tell

-- paste source info and timestamp into predefined position of the specified TextEdit file
tell application "TextEdit"
activate
tell application "System Events"
tell process "TextEdit"
keystroke (ASCII character 31) using command down
keystroke return
keystroke return
keystroke "v" using {command down}
delay 0.1
end tell
end tell
end tell

-- copy content of specified TextEdit file
tell application "TextEdit"
activate
tell application "System Events"
tell process "TextEdit"
keystroke "a" using {command down}
keystroke "c" using {command down}
delay 0.1
end tell
end tell
end tell

-- delete content of specified TextEdit file
tell application "TextEdit"
activate
tell application "System Events"
tell process "TextEdit"
keystroke "a" using {command down}
keystroke "x" using {command down}
delay 0.1
end tell
end tell
end tell

-- save specified TextEdit file and quit TextEdit
tell application "TextEdit"
save "Macintosh HD:Users:Web:Documents:Web Text Clips:Web_Text_Clips.rtf"
quit
end tell


I was forced into this workaround because when I used the “set” command the embedded links got expunged from the selected web text.

While this script does work it is quite cumbersome and slow. I have tried all sorts of different things (including some shell script commands) but so far nothing else has worked.

Can anyone help me in creating a more elegant and faster script that still maintains the embedded links in the selected web text?

Thanks,

I am running MacOS Sierra (Version: 10.12.6)

Answer Source

Here's the script (a Cocoa-AppleScript) to copy the selection to the clipboard, and to append some text to the clipboard's HTML data.

use framework "Foundation"
use scripting additions

set beginningStr to return & return & "- - - - - " & return & "From: "
set theLongDate to current date
tell application "Safari"
    if (do JavaScript "document.execCommand('copy')" in document 1) then -- copy the selection to the clipboard 
        set {theTitle, theURL} to {name, URL} of the front document
        set writeString to beginningStr & theURL & return & "Page Title: " & theTitle & return & "Date: " & theLongDate
        set r to my appendStringToClipboard(writeString, theURL, length of beginningStr)
        if r is "" then
            my goToNoteApp()
        else
            display alert r
        end if
    else
        display alert "Error: can't copy to clipboard, check the selection"
    end if
end tell

on goToNoteApp() --**** you must change the name of the application to the name of your note-taking app 
    activate application "Notes"
    -- now you can paste
end goToNoteApp

on appendStringToClipboard(t, u, n) -- params:  t = the text to append, u = the url, n = the number of characters in the text before the url
    tell current application
        set pboard to its NSPasteboard's generalPasteboard()
        -- ** if the clipboard contains HTML data **
        if (pboard's availableTypeFromArray:{its NSPasteboardTypeHTML}) is missing value then return "No HTML data  in the clipboard"
        set tData to (pboard's stringForType:(its NSPasteboardTypeHTML))'s dataUsingEncoding:(its NSUnicodeStringEncoding) -- get the HTML data

        set attrString to its (NSMutableAttributedString's alloc()'s initWithHTML:tData documentAttributes:(missing value)) -- get an attributed string from the HTML data
        if attrString is missing value then return "The HTML data can’t be decoded."
        set t_RTFD to (pboard's availableTypeFromArray:{its NSRTFDPboardType}) -- if the clipboard contains an image

        set myFont to its (NSFont's fontWithName:"Helvetica" |size|:14) -- *** the font and the size of the appended text (you can change it) ***
        set myColor to its (NSColor's blackColor()) -- *** the color of the appended text (you can change it)***

        set theDict to its (NSDictionary's alloc()'s initWithObjectsAndKeys_(myColor, its NSForegroundColorAttributeName, myFont, its NSFontAttributeName, missing value))
        set stringToAppend to its ((NSMutableAttributedString's alloc)'s initWithString:t attributes:theDict) -- create an attributed string ( the text, url, title and the timestamp )
        stringToAppend's addAttribute:(its NSLinkAttributeName) value:u range:{location:n, |length|:length of u} -- add attribute for the URL  (make a clickable link)
        attrString's appendAttributedString:stringToAppend ---  append the text, the url, the title and the timestamp to the attrString (the contents of the selection)
        pboard's declareTypes:{its NSPasteboardTypeRTF, its NSPasteboardTypeHTML} owner:me

        -- *** the HTML data and the appended text ***
        set {tData, err} to attrString's dataFromRange:{location:0, |length|:attrString's |length|()} documentAttributes:{DocumentType:"NSHTML"} |error|:(reference)
        pboard's setData:tData forType:(its NSPasteboardTypeHTML) ---- put the new HTML data into the clipboard

        -- *** the  RTF data and the appended text ***
        set tData to attrString's RTFFromRange:{location:0, |length|:attrString's |length|()} documentAttributes:{DocumentType:"NSRTF"}
        pboard's setData:tData forType:(its NSPasteboardTypeRTF) ---- put the new RTF data into the clipboard

        if t_RTFD is not missing value then -- the clipboard contains an image
            -- *** the  RTFD data and the appended text ***
            pboard's addTypes:{its NSPasteboardTypeRTFD} owner:me -- add the RTFD type
            set tData to attrString's RTFDFromRange:{location:0, |length|:attrString's |length|()} documentAttributes:{DocumentType:"NSRTFD"}
            pboard's setData:tData forType:(its NSPasteboardTypeRTFD) ---- put the new RTFD data into the clipboard
        end if
        return ""
    end tell
end appendStringToClipboard

If you do not need to get images from the selection, remove these lines in the script:

if t_RTFD is not missing value then -- the clipboard contains an image
    -- *** the  RTFD data and the appended text ***
    pboard's addTypes:{its NSPasteboardTypeRTFD} owner:me -- add the RTFD type
    set tData to attrString's RTFDFromRange:{location:0, |length|:attrString's |length|()} documentAttributes:{DocumentType:"NSRTFD"}
    pboard's setData:tData forType:(its NSPasteboardTypeRTFD) ---- put the new RTFD data into the clipboard
end if