Insert characters before and after selected text then paste clipboard

I am trying to automate a markdown action. Here is what I want the program to do:

  • Assume the user has just copied a URL to the clipboard.

  • He then switches to his editor and highlights a phrase in the open document.

  • He then invokes the script.

  • It immediately inserts a “[” (left bracket) character before the selected text and a “]” (right bracket) after the selected text.

  • The script then inserts an open “(” (open paren) character, pastes the URL from the clipboard, then inserts a “)” (closed paren) character.

The completed text string look similar to the following:

selectedtext

This should be simple, but I can’t figure it out. Can someone provide a snippet? Thanks so much.

Model: MacBook Air
AppleScript: 2.4.3
Browser: Safari 536.11
Operating System: Mac OS X (10.7)

Since you haven’t specified your editor, this uses standard Mac OS copy and paste keystrokes. The editor will need to be frontmost throughout the process:

tell application "TextEdit" to activate -- Edit as necessary or omit.

-- Get the clipboard contents into the script.
set clip to (the clipboard)
-- Get the selected text into the clipboard.
tell application "System Events" to keystroke "c" using {command down}
repeat while ((the clipboard) is clip)
	delay 0.2
end repeat
-- Compose the end result.
set endResult to "[" & (the clipboard) & "](" & clip & ")"
-- Place it on the clipboard.
set the clipboard to endResult
repeat until ((the clipboard) is endResult)
	delay 0.2
end repeat
-- Paste it over the selected text.
tell application "System Events" to keystroke "v" using {command down}
-- Restore the original clipboard contents.
set the clipboard to clip

Thanks Nigel, although I didn’t post the request that was just what I was looking for!

Good. Thanks for the feedback! :slight_smile:

I concur! This is one of the pieces amiss when doing markdown, I just never to around to say snagged! :slight_smile:

For IMHO markdown is really the way to go when editing text. It looks good, and in TextWrangler and BBEdit you also get your text sectioned, so you can jump to specific parts or sub parts of it from the function bar.

So nifty! Really helping you editing.

Thanks Nige!l

Hello!

This is indeed so useful, so I came around to make a version for BBEdit and TextWrangler (just change app name to BBedit)


” Markdown link http://macscripter.net/edit.php?id=154223
” © McUsr 2012 and put in public domain You. may not post it elsewhere, what so ever your reason.
property ScriptTitle : "Markdown Links"
property infoIcon : a reference to file ((path to library folder from system domain as text) & "CoreServices:CoreTypes.bundle:Contents:Resources:AlertNoteIcon.icns")


set {clipFail, clipMissing, selMissing, failure} to {false, false, false, false}
tell application "TextWrangler"
	activate
	set idOfFrontApp to my getfrontAppId()
	try
		
		-- Get the clipboard contents into the script.
		set theSel to (get selection of text window 1 as text)
		if theSel = "" then
			error number 3020
		else
			set clip to (the clipboard) as text
			if clip = "" then
				error number 3005
			else
				-- check to see if it is an url 		
				if clip does not start with "http://" then
					if clip does not start with "file://" then
						error number 3010
					end if
				end if
			end if
			-- Get the selected text into the clipboard.
			set the selection of text window 1 to "[" & theSel & "] (" & clip & ")"
		end if
	on error e number n
		if n is 3005 then
			set clipMissing to true
		else if n is 3010 then
			set clipFail to true
		else if n = 3020 then
			set selMissing to true
		else
			set {f, m} to {e, n}
		end if
		set failure to true
	end try
end tell

if failure = true then
	
	if clipFail then
		alertDialog({aTextMessage:"There were no valid url on the clipboard!", aTextTitle:my ScriptTitle, timeInSecs:300, btnAsList:{"Ok"}, iconAsFileRef:infoIcon, bundleIdOfFrontApp:idOfFrontApp})
		
	else if clipMissing then
		alertDialog({aTextMessage:"There were no contents on the clipboard!", aTextTitle:my ScriptTitle, timeInSecs:300, btnAsList:{"Ok"}, iconAsFileRef:infoIcon, bundleIdOfFrontApp:idOfFrontApp})
		
	else if selMissing then
		alertDialog({aTextMessage:"There is no selected text in your document", aTextTitle:my ScriptTitle, timeInSecs:300, btnAsList:{"Ok"}, iconAsFileRef:infoIcon, bundleIdOfFrontApp:idOfFrontApp})
		
	else
		alertDialog({aTextMessage:"An error has occured: " & return & f & return & m as text, aTextTitle:my ScriptTitle, timeInSecs:300, btnAsList:{"Ok"}, iconAsFileRef:infoIcon, bundleIdOfFrontApp:idOfFrontApp})
	end if
	abortNicely({bundleIdFrontApp:idOfFrontApp})
end if

on alertDialog(R) -- Returns Nothing
	-- R : {aTextMessage:theMessage,aTextTitle:thetitle,timeInSecs:lenToTimeout,btnAsList:theButton,iconAsFileRef:theIcon,bundleIdOfFrontApp:frontappId}
	local res, failed, e, n
	set failed to false
	tell application "SystemUIServer"
		activate
		try
			if (iconAsFileRef of R) is null then
				set res to button returned of (display dialog (aTextMessage of R) with title (aTextTitle of R) giving up after (timeInSecs of R) buttons (btnAsList of R) default button 1)
			else
				set res to button returned of (display dialog (aTextMessage of R) with title (aTextTitle of R) giving up after (timeInSecs of R) buttons (btnAsList of R) default button 1 with icon (iconAsFileRef of R))
			end if
			if res = "" then set failed to true
		on error e number n
			set failed to true
			
		end try
	end tell
	if failed is true then
		abortNicely({bundleIdFrontApp:(bundleIdOfFrontApp of R)}) -- Returns Nothing
	end if
	return
end alertDialog

on getfrontAppId() -- Returns bundleid of active app
	local frontappId
	set frontappId to ""
	tell application "System Events"
		set frontappId to bundle identifier of first application process whose frontmost is true
	end tell
	return frontappId
end getfrontAppId

on abortNicely(R) -- Returns Nothing
	
	tell application "System Events" to tell application process id (bundleIdFrontApp of R)
		key down control
		key code 118
		key up control
	end tell
	error number -128
end abortNicely

Here is another take on the same workflow, I have called it SafariEndReference.

This script is to be run, when you want to insert an end reference into the document, looking like this:

[id]: http://example.com/longish/path/to/resource/here "Optional Title Here"


tell application "Safari"
    tell current tab of window 1
        do JavaScript "self.focus()"
        set tabsName to (get name)
        set tabsURL to (get URL)
    end tell
end tell

set markdownLink to "[id]: " & tabsName & return & tab & tabsURL

tell application "BBEdit"
    set the selection of text window 1 to markdownLink
end tell

Simplyfied with a little help from StefanK

Here is yet another take on the same thing, this time it puts in a direct reference into the markdown document. I have called it SafariDirectReference

The result looks like this:

[MacScripter / Post a reply](http://macscripter.net/post.php?tid=39122)

” http://macscripter.net/edit.php?id=154223
” © McUsr 2012 and put in public domain You. may not post it elsewhere, what so ever your reason.
tell application "Safari"
    tell current tab of window 1
        do JavaScript "self.focus()"
        set tabsName to (get name)
        set tabsURL to (get URL)
    end tell
end tell
set markdownLink to "[" & tabsName & "](" & tabsURL & ")"
tell application "BBEdit"
    set the selection of text window 1 to markdownLink
end tell

Simplyfied with a little help from StefanK

easier


tell application "Safari"
	tell current tab of window 1
		do JavaScript "self.focus()"
		set tabsName to (get name)
		set tabsURL to (get URL)
	end tell
end tell

Thanks! :slight_smile:

Hello!

Here is one that makes a direct reference to put into a markdown document based on the current pdf file in Skim, which is free versatile, and scriptable, (but can’t set keyword through Get Info, like Preview can!).

I use this for documentation, when doing a project, as I then later on, can just click the link on the project page to reopen!


” Skim Direct Reference http://macscripter.net/edit.php?id=154223
” © McUsr 2012 and put in public domain You. may not post it elsewhere, what so ever your reason.
property Scripttitle : "Skim Direct Reference"
property cliptextIcon : a reference to file ((path to library folder from system domain as text) & "CoreServices:CoreTypes.bundle:Contents:Resources:ClippingText.icns")
on run
	tell application id "com.apple.systemevents"
		set e to name of first process whose frontmost is true
	end tell
	tell application "Skim" to set {a, b} to get {file, name} of document of its window 1
	tell application "Finder" to set c to URL of (a as alias)
	
	set the clipboard to "[" & b & "](" & c & ")"
	tell application "SystemUIServer"
		activate
		display dialog "Reference on clipboard" with title Scripttitle buttons {"Ok"} default button 1 with icon cliptextIcon giving up after 1.1
	end tell
	tell application e to activate
	return 0
end run

Hello!

Those below, are work in progress, but it is what I got so far for making Settex headings

How it works:

You place the cursor under the text of the heading and run the script to produce the settex heading.

Example output:

This look so much better

Settex level 1 heading by settex1

So does this
””””””””

Settex level 2 heading by settex2

Than this

Which is a normal markdown heading.

This does pertain when you edit the text of course, and if you
don’t convert the markdown to some other format, but sends
it away as raw text.

So below are settex1 and settex2 scripts for BBEdit that can easily be for TextWrangler, by changing app name!

settex1


” settex1 http://macscripter.net/edit.php?id=154223
” © McUsr 2012 and put in public domain You. may not post it elsewhere, what so ever your reason.
on run
	local a, b, c, d, ts, tpos
	tell application "BBEdit"
		tell document of its text window 1
			set a to selection of its text
			set b to startLine of a
			set c to b - 1
			set d to length of line c
			set ts to ""
			repeat with i from 1 to d
				set ts to ts & "="
			end repeat
			set contents of a to ts
			set tpos to (characterOffset of a) + (length of ts) - 1
			select insertion point after character tpos of its text
		end tell
	end tell
end run

settex2


” settex2 http://macscripter.net/edit.php?id=154223
” © McUsr 2012 and put in public domain You. may not post it elsewhere, what so ever your reason.
on run
	local a, b, c, d, ts, tpos
	tell application "BBEdit"
		tell document of its text window 1
			set a to selection of its text
			set b to startLine of a
			set c to b - 1
			set d to length of line c
			set ts to ""
			repeat with i from 1 to d
				set ts to ts & "-"
			end repeat
			set contents of a to ts
			set tpos to (characterOffset of a) + (length of ts) - 1
			select insertion point after character tpos of its text
		end tell
	end tell
end run

Here is one for getting the current safari Url put into a BBCode Url.



-- BBcoding Safari Url http URL://macscripter.net/edit.php?id=154655
-- © McUsr and put into public domain you may not post this anywhere else, what so ever!

property Scripttitle : "BBcoding Safari Url"
property cliptextIcon : a reference to file ((path to library folder from system domain as text) & "CoreServices:CoreTypes.bundle:Contents:Resources:ClippingText.icns")
on run
    tell application id "com.apple.systemevents"
        set e to name of first process whose frontmost is true
    end tell
    tell application "Safari"
        activate
        try
            tell its window 1
                tell current tab
                    set a to its name
                    set b to its URL
                end tell
            end tell
        on error
            tell its window 2
                tell current tab
                    set a to its name
                    set b to its URL
                end tell
            end tell
        end try
    end tell
    set the clipboard to "[url= & b & ]" & a & "[/url]"
    tell application "SystemUIServer"
        activate
        display dialog "Reference on clipboard" with title Scripttitle buttons {"Ok"} default button 1 with icon cliptextIcon giving up after 1.1
    end tell
    tell application e to activate
    return 0
end run

There is a bug in bbcode: the line should be

 set the clipboard to "[url= & b & ]" & a & "[/url]"

not

set the clipboard to "[url= & b & ]" & a & "[/url]"

:smiley: Add the missing hyphens yourself!

Here is a script that will return the original url from a saved webarchieve.

If you choose the dialog, like all those scripts, then the information is stored on the clipboard.

Usage
You choose one or more webarchieves from a Finder or Spotlight window, then runs the script.


property version : 2 as integer
property Scripttitle : "WebArchieve's Origin"
--http://macscripter.net/viewtopic.php?id=24765 Idea by Adam Bell
-- WebArchieve's Origin http://macscripter.net/edit.php?id=154661
-- © McUsr and put into public domain you may not post this anywhere else, what so ever!
property genericIcon : a reference to file ((path to library folder from system domain as Unicode text) & "CoreServices:CoreTypes.bundle:Contents:Resources:GenericEditionFileIcon.icns")
set infoIcon to a reference to file ((path to library folder from system domain as text) & "CoreServices:CoreTypes.bundle:Contents:Resources:AlertNoteIcon.icns")
set idOfFrontApp to getfrontAppId()
set ReportText to ""
set failed to false
try
	
	tell application "Finder"
		activate
		set selected_items_list to (get selection) as alias list
		
		set selCount to count selected_items_list
		
		if selCount ≠ 0 then set last_item to the last item of the selected_items_list as text
		
		try
			set startPath to target of its Finder window 1 as alias
		on error
			set starpath to path to desktop folder
		end try
		
	end tell
	
	
	if selCount = 0 then
		tell application "SystemUIServer"
			activate
			try
				set the selected_items_list to (choose file with prompt "Choose the .webarchieves  or .pdf's you want to see info for for" default location startPath with multiple selections allowed)
			on error
				set failed to true
			end try
		end tell
		
		set selCount to count selected_items_list
		if ((count of the selected_items_list) = 0) or failed then
			alertDialog({aTextMessage:"No .webarchieves or .pdf's are selected.", aTextTitle:my Scripttitle, timeInSecs:300, btnAsList:{"Ok"}, iconAsFileRef:infoIcon, bundleIdOfFrontApp:idOfFrontApp})
			abortNicely({bundleIdFrontApp:idOfFrontApp})
		end if
		set last_item to the last item of the selected_items_list as text
		
	end if
	
	set failed to false
	tell application "SystemUIServer"
		activate
		try
			set outputType to button returned of (display dialog "Please choose form of output" with title Scripttitle buttons {"Cancel", "Report", "Dialogs"} cancel button 1 default button 3 with icon genericIcon)
		on error
			set failed to true
		end try
	end tell
	if failed then abortNicely({bundleIdFrontApp:idOfFrontApp})
	
	repeat with this_item in the selected_items_list
		if outputType is "Dialogs" then
			set ReportText to ""
		end if
		
		
		set usageReport to showBaseUrl for (this_item as alias)
		
		if outputType is "Report" then
			set ReportText to ReportText & return & "==================================" & return & return
		else
			set ReportText to ReportText & return
		end if
		
		set ReportText to ReportText & usageReport & return & return
		
		if outputType is "Dialogs" then
			set the clipboard to ReportText
			if contents of this_item is the last_item or selCount is 1 then
				set the button_list to {"Done"}
			else
				set the button_list to {"Cancel", "Next"}
			end if
			-- display the information
			with timeout of 900 seconds
				tell application "SystemUIServer"
					activate
					
					display dialog ReportText with title Scripttitle buttons the button_list default button (the last item of the button_list)
				end tell
			end timeout
		end if
	end repeat
	if outputType is "Report" then
		
		tell application "TextEdit"
			activate
			make new document at the front
			set text of front document to "F i l e   i n f o r m a t i o n " & return & ReportText
		end tell
	end if
on error e number n
	if not failed then
		alertDialog({aTextMessage:e & " " & n, aTextTitle:my Scripttitle, timeInSecs:300, btnAsList:{"Ok"}, iconAsFileRef:infoIcon, bundleIdOfFrontApp:idOfFrontApp})
		abortNicely({bundleIdFrontApp:idOfFrontApp})
	end if
end try

on showBaseUrl for tFile
	local tpapth, tName, MD, tOrigin, Usage, theText, ofs
	set tPath to quoted form of (POSIX path of tFile)
	set tName to name of (info for tFile)
	set MD to do shell script "mdls -raw -name kMDItemWhereFroms " & tPath
	set tid to AppleScript's text item delimiters
	set AppleScript's text item delimiters to "("
	set tOrigin to text item -1 of MD
	set AppleScript's text item delimiters to ")"
	set tOrigin to (text item 1 of tOrigin) as text
	set AppleScript's text item delimiters to return
	set tOrigin to text items of tOrigin
	set AppleScript's text item delimiters to tid
	set Usage to {}
	--  on suggestion from  DJ Bazzie Wazzie
	if (count tOrigin) is 1 then
		set theText to "The file \"" & tPath & "\" Doesn't have an origin!" & return & return
		return theText
	end if
	
	repeat with k from 2 to ((count tOrigin) - 1)
		set ofs to offset of "\"" in (item k of tOrigin)
		set Usage's end to (text (ofs + 1) thru -2 of item k of tOrigin) & return
	end repeat
	set Usage to Usage as text
	set theText to "The file \"" & tPath & "\" is coming from:" & return & return & Usage
	return theText
end showBaseUrl

on getfrontAppId() -- Returns bundleid of active app
	local frontappId
	set frontappId to ""
	tell application "System Events"
		set frontappId to bundle identifier of first application process whose frontmost is true
	end tell
	return frontappId
end getfrontAppId


on abortNicely(R) -- Returns Nothing
	
	tell application "System Events" to tell application process id (bundleIdFrontApp of R)
		key down control
		key code 118
		key up control
	end tell
	error number -128
end abortNicely

on alertDialog(R) -- Returns Nothing
	-- R : {aTextMessage:theMessage,aTextTitle:thetitle,timeInSecs:lenToTimeout,btnAsList:theButton,iconAsFileRef:theIcon,bundleIdOfFrontApp:frontappId}
	local res, failed, e, n
	set failed to false
	tell application "SystemUIServer"
		activate
		try
			if (iconAsFileRef of R) is null then
				set res to button returned of (display dialog (aTextMessage of R) with title (aTextTitle of R) giving up after (timeInSecs of R) buttons (btnAsList of R) default button 1)
			else
				set res to button returned of (display dialog (aTextMessage of R) with title (aTextTitle of R) giving up after (timeInSecs of R) buttons (btnAsList of R) default button 1 with icon (iconAsFileRef of R))
			end if
			if res = "" then set failed to true
		on error e number n
			set failed to true
			
		end try
	end tell
	if failed is true then
		abortNicely({bundleIdFrontApp:(bundleIdOfFrontApp of R)}) -- Returns Nothing
	end if
	return
end alertDialog


Here is a script that reveals the file shown in a Safari tab so I can run the script above, or any other!


-- Reveal file from Browser http://macscripter.net/edit.php?id=154661
-- © McUsr and put into public domain you may not post this anywhere else, what so ever!
property Scripttitle : "Reveal file from Browser"
property warnIcon : a reference to file ((path to library folder from system domain as text) & "CoreServices:CoreTypes.bundle:Contents:Resources:AlertCautionIcon.icns")
on run
	local e, failure, tabsURL, txt, newtxt
	tell application id "com.apple.systemevents"
		set e to name of first process whose frontmost is true
	end tell
	set failure to false
	tell application "Safari"
		activate
		tell current tab of window 1
			do JavaScript "self.focus()"
			set tabsURL to (get URL)
		end tell
	end tell
	
	if tabsURL starts with "file" then
		set txt to text 8 thru -1 of tabsURL
		set newtxt to decode_text(txt)
		do shell script "open -R " & quoted form of newtxt
	else
		tell application "SystemUIServer"
			activate
			display dialog "This script works with webarchievs and pdfs" with title Scripttitle buttons {"Ok"} default button 1 with icon warnIcon
			set failure to true
		end tell
		
	end if
	if failure then
		tell application e to activate
	else
		tell application "Finder" to activate
	end if
	return 0
end run

-- New decoding curtsey of DJ Bazzie Wazzie

on decode_text(this_text)
	return my rawURLDecode(this_text)
end decode_text

on rawURLDecode(str)
	return do shell script "/bin/echo -n " & quoted form of str & " | php -r ' echo rawurldecode(fgets(STDIN)); '"
end rawURLDecode

Hello!

I have removed a little bug from the script in post #14, and updated the text to reflect that unfortunately, the URL of a pdf document isn’t stored in a kMDItemWhereFroms field in Spotlight Meta data.

Hi!

Here is one that gives you a direct Markdown link for the front document in Preview, once you have “made” Preview “scriptable”. (You may read some properties in my experience, not much more.)

Oops… The latest version of Mac Osx this works with in a clean way is with Snow Leopard. :frowning:


property scripttitle : "Preview direct markdown link"
property cliptextIcon : a reference to file ((path to library folder from system domain as text) & "CoreServices:CoreTypes.bundle:Contents:Resources:ClippingText.icns")
-- © McUsr 2012 and put into public domain you may not post this anywhere else, or store it in a puclicly accessible repository.
” Please refer to this link: http://macscripter.net/edit.php?id=154655
tell application "Preview"
	tell its document 1
		try
			set a to (get path of it)
			set d to a
		on error
			activate
			display alert "The Pdf document isn't saved, and hence has no path!
Save and try again!" buttons {"Ok"} default button 1
			error number -128
		end try
		set b to name
	end tell
end tell

tell application "Finder"
	set c to URL of file ((POSIX file a) as alias)
end tell
set the clipboard to "[" & b & "](" & c & ")"
tell application "SystemUIServer"
	display dialog "The markdown link is put onto the clipboard" with title scripttitle with icon cliptextIcon buttons {"Ok"} giving up after 1.1
	
end tell

Hello

May we apply the same trickery allowing Preview scripting on the gatekeeper aware version ?

It seems that the answer is : we can’t.

Under 10.8.1, in Preview 6.0, I added the property :

NSAppleScriptEnabled - string - Yes
to the info.plist file and every attempt to open a picture (png) file gave an application cash.

Yvan KOENIG (VALLAURIS, France) dimanche 2 septembre 2012 11:03:51

No, you have indeed to make a copy first, and then more, I think you have to sign your copy afterwards. So, lets say that this only works through Lion!

Though there may be, at least there used to be a post over at redsweater.com explaining how to do it: Red Sweater Blog “ Minimal Scriptability Read the whole thread I hope you manage to mend it again Yvan, or at least that you only need to reinstall Preview, and that you know how to do that, or finds out, I don’t have Lion or Mountain Lion, unfortunately. I should have been clear about the version and the consequences. I was tired when I uploaded the working script, and I guess I took to much for granted, and for that I am truly sorry! :frowning:

Hopefully you can reinstall it from Time Machine.

However, while I am at this, when I did this with Console.app under Snow Leopard, it became fully scriptable, in the sense that I now can move windows.

Hello

I’m not completely fool, I did the trick on a copy.
Always under 10.8.1, with the informations given in the passed link, I got :

codesign -f -s - /Applications/HackPreview.app
/Applications/HackPreview.app: replacing existing signature
/Applications/HackPreview.app: object file format unrecognized, invalid, or unsuitable

And the script :

tell application “HackPreview”
get name of document 1
end tell

issue :
error “Erreur dans HackPreview : Il est impossible d’obtenir name of document 1.” number -1728 from name of document 1

I will try to run the system in English for see.

Same behavior with 10.8.1 ran in English.
The error message is now :

error “HackPreview got an error: Can’t get name of document 1.” number -1728 from name of document 1

I think that I will file a report to Apple asking them to give use access to the Standard Suite in the official release.
I just wait for some feedback from 10.8 users to see if they get the same behavior.

Yvan KOENIG (VALLAURIS, France) dimanche 2 septembre 2012 16:11:59