BBEdit - Strip Outer HTML tags

So, I monitor the BBEdit Google group, now that I’m a paid-up BBEdit user. One question piqued my interest today, and here is my solution:

 1 tell application "BBEdit"
 2 	tell front window
 3 		set cursorPos to characterOffset of selection
 4 		balance tags
 5 		set startPos to characterOffset of selection
 6 		set endPos to startPos + (length of selection)
 7 		select (characters (startPos - 6) thru (endPos + 6))
 8 		set selectedText to selection as text
 9 		if characters 1 thru 6 of selectedText as text is equal to "<span>" then
10 			set replaceText to characters startPos thru (endPos - 1) as text
11 			set selection to replaceText
12 			select insertion point before character (cursorPos - 6)
13 		else
14 			select insertion point before character (cursorPos)
15 		end if
16 	end tell
17 end tell

In summary, it uses the BBEdit builtin command to select the contents of the current tag, and then extends that selection to grab the span tags that surround it. If indeed it was as span block, then it removes those tags.

This is just a simple one-off, but it might be useful as a basis for generating a script that has more features: like arbitrary tag types (rather than just span), or some other thing I haven’t thought of.

Note that it will only strip the outer tags. BBEdit has a Remove Markup feature, but that does not seem to be accessible using AppleScript.

Address Book: Family Relationships

I have a fairly large address book.488 contacts, who are shared between my various hobbies and pastimes. Including a large number of people who are related to one another. In some of these cases, I have populated the Related Names field, often where I just need to know a child’s parents names, but also in other cases where the related person is also in my address book.

I have several groups of people who are siblings, and I could go through each sibling and add in ‘father, mother, sister, brother’ items for each sibling, but it would be great if this could be done automatically.

The father/mother bit should be relatively straightforward, since the fields are the same:

Bob and Alice have two children, Carol and David. If I have put father:Bob and mother:Alice in for Carol, and I put brother:David in, then the system should be able to easily put father:Bob and mother:Alice in for David.

The tricky bit is with gender related to siblings. There is no default field for gender in Address Book, so how does the system know if David should have sister:Carol or brother:Carol? Especially since I don’t want to have to hand-code a list of names and which gender they are. I have many people with unusual names, and some with non-gender-specific names.

A short-term solution might be to (a) see if there are other sibling relationships (ie, if there is also brother:Eric, and Eric has sister:Carol, then clearly Carol is a female, and David should also have sister:Carol); or (b) have a temporary sibling:Carol field, which can be changed by the user.

You could then have a Smart Address Book Group which has all people with a sibling: field, which would make finding those people easier.

Conceivably, this should be possible with AppleScript. I have, however, butted heads with Address Book’s scripting in the past. It doesn’t always seem to be that easy to get data from this application.

Perhaps this type of feature, as well as my other hope for Address Book (notice if two contacts have the same number, including just the last X digits (for +614 vs 04 numbers in Australia, which are the same), and allow manipulation of this data, might appear in Leopard.

iCal and Invitations

I’ve used Gmail/Calendar, and have just migrated my data back to iCal, since now I have a laptop it makes a bit more sense to have the data stored locally. There is one thing I’d like to see possible in both systems is to mark a meeting attendee as attending. It only appears to be possible to do this from the person themselves. Sometimes I speak to an attendee of a function, and they are coming, but the email or calendar system they are using does not integrate well with iCal/gCal, so the email is sent back, and I need to modify stuff manually. Google Calendar at least allows you to add “Guests”, something I haven’t yet figured out how to do with iCal. However, with iCal, it appears to be possible to script iCal, so I may be able to add this functionality.

Getting Finder Comments in different languages

bash: mdls filename | grep FinderComment AppleScript: tell application "Finder"     comment of file end tell python: #!/usr/bin/pythonw from appscript import * path = '/Users/NAME/your/path/here' comment = app('Finder').items[path.replace('/', ':')].comment.get()

Waiting for an Application to launch

I use an AppleScript to implement “Open Terminal Here” functionality on my Macs, and just now I noticed on the Intel machine it had stopped working properly if Terminal wasn’t already running. For some reason, on PPC it still sends the message through, but on x86 it doesn’t. So, I had to use the following code to get it to work if Terminal wasn’t already running, which can be generalised to any application: repeat while "Terminal" is not in name of processes     delay 0.5 end repeat The whole script, which can be saved as an application bundle, set to not show in dock, and then placed in the Toolbar:

 1     -- when the toolbar script icon is clicked
 2     --
 3     on run
 4     	tell application "Finder"
 5     		activate
 6     		try
 7     			set this_folder to (the target of the front window) as alias
 8     			--display dialog POSIX path of this_folder
 9     		on error
10     			set this_folder to startup disk as alias
11     		end try
12     		my process_item(this_folder)
13     	end tell
14     end run
18     -- This handler processes folders dropped onto the toolbar script icon
19     --
20     on open these_items
21     	repeat with i from 1 to the count of these_items
22     		set this_item to item i of these_items
23     		my process_item(this_item)
24     	end repeat
25     end open
28     -- this subroutine processes does the actual work
29     --
30     on process_item(this_item)
31     	tell application "System Events"
32     		try
33     			get process "Terminal"
35     			tell application "Terminal"
36     				activate
37     				do script "cd " & (quoted form of POSIX path of this_item)
38     			end tell
39     		on error -- Terminal Not running, launch and run in first window.
40     			launch application "Terminal"
41     			-- May need to wait until Terminal finishes launching
42     			repeat while "Terminal" is not in name of processes
43     				delay 0.5
44     			end repeat
45     			tell application "Terminal"
46     				activate
47     				-- So we don't create a new window: in window 1
48     				do script "cd " & (quoted form of POSIX path of this_item) in window 1
49     			end tell
50     		end try
51     	end tell
52     end process_item

Scripting iTunes 7

There are a few new things in AppleScript support for iTunes 7.


downloaded (boolean, r/o) : was this artwork downloaded by iTunes?


special kind (none/Audiobooks/folder/Movies/Music/Party Shuffle/Podcasts/Purchased Music/TV Shows/Videos, r/o) : special playlist kind

episode ID (Unicode text) : the episode ID of the track
episode number (integer) : the episode number of the track
gapless (boolean) : is this track from a gapless album?
season number (integer) : the season number of the track
skipped count (integer) : number of times this track has been skipped
skipped date (date) : the date and time this track was last skipped
show (Unicode text) : the show name of the track
video kind (none/movie/music video/TV show) : kind of video track

Most of these are expected with the addition of the new features: gapless playback and TV/Movie support. At least now we can programmatically change the tags for TV shows. There are two there that are quite interesting: skipped count/date.

They are available as columns in the list views too, I just hadn’t noticed them yet. Now it will be possible to have smart playlist additions like: skipped count < 2.

Searching Zen

I googled for HTMLify Applescript, wanting to find out some simple code for how to escape the text in an AppleScript string, so I can pass it as arguments to a URL. My site came up with the top link. I was hoping for a better solution to the one I had come up with!

Better iTunes Data Insert

I’ve updated my Insert iTunes Data (HTML) script for generating a block of text that describes the current playing iTunes track. This version links to the iTunes Music Store, rather than Google. It is relatively smart, in that the track name link also has the artist name, and the album name does too, as long as the album isn’t a compilation. The only (slight) bug is that the track name seems to need to be just the way iTMS displays it, so having (Live) might stuff up a link. This might be only if there isn’t a Live version in the iTMS.

I Can’t Tell You Why (Live)EaglesHell Freezes Over ★★★★★

Code after the jump.

 1     -- Insert some data about the currently playing iTunes track into browser.
 3     property star : «data utxt2605» as Unicode text
 4     property half : «data utxt00BD» as Unicode text
 5     property quarter : «data utxt00BC» as Unicode text
 6     property threeq : «data utxt00BE» as Unicode text
 7     property browser : "Firefox"
 8     property URLprefix : "itms://"
10     on run {}
12     	tell application "System Events"
13     		try
14     			get process "iTunes"
15     		on error
16     			return "No Track"
17     		end try
18     	end tell
20     	tell application "iTunes"
21     		set theTrack to current track
22     		set theArtist to artist of theTrack
23     		set theAlbum to album of theTrack
24     		set theRating to rating of theTrack
25     		set theComp to compilation of theTrack
26     		set theTrack to name of theTrack
27     		--set trackInfo to {theTrack, theArtist, theAlbum, theRating}
28     	end tell
30     	set trackLink to "<a href='" & URLprefix & "songTerm=" & HTMLify(theTrack) & "&amp;artistTerm=" & HTMLify(theArtist) & "'>" & theTrack & "</a>"
31     	set artistLink to "<a href='" & URLprefix & "artistTerm=" & HTMLify(theArtist) & "'>" & theArtist & "</a>"
32     	if theComp is true then
33     		set theArtist to "" -- No Artist if album is compilation!
34     	end if
35     	set albumLink to "<a href='" & URLprefix & "albumTerm=" & HTMLify(theAlbum) & "&amp;artistTerm=" & HTMLify(theArtist) & "'>" & theAlbum & "</a>"
37     	set theString to "<p class='itunes'> " & trackLink & " • " & artistLink & " • " & albumLink & " " & myRating(theRating) & "</p>"
39     	set the clipboard to theString
41     	tell application browser
42     		activate
43     		tell application "System Events" to keystroke "v" using {command down}
44     	end tell
45     end run
47     on HTMLify(someText)
48     	set someText to replace(someText, "&", "&amp;")
49     	set someText to replace(someText, "\"", "&quot;")
50     	set someText to replace(someText, "<", "&lt;")
51     	set someText to replace(someText, ">", "&gt;")
52     	set someText to replace(someText, " ", "+")
53     	set someText to replace(someText, "'", "&apos;")
54     	return someText
55     end HTMLify
57     on replace(theText, find, replace)
58     	-- Nice replace function
59     	set OldDelims to AppleScript's text item delimiters
60     	set AppleScript's text item delimiters to find
61     	set newText to text items of theText
62     	set AppleScript's text item delimiters to replace
63     	set theResult to newText as text
64     	set AppleScript's text item delimiters to OldDelims
65     	return theResult
66     end replace
68     on myRating(theRating)
69     	set theResult to ""
70     	repeat 5 times
71     		if theRating  20 then
72     			set theResult to theResult & star
73     		else if theRating  10 then
74     			set theResult to theResult & half
75     		end if
76     		set theRating to theRating - 20
77     	end repeat
78     	return theResult
79     end myRating

One More TimeDaft PunkTriple J Hottest 100 - Volume 9 ★★★

Resizing Images in AppleScript/Automator

I’ve already written a small Automator application that will resize an image to 640x480, but what about if I want to change it to a different size. There’s no way to set the resize amount on the fly in Automator, so I thought, it should be easy to do it in AppleScript. Except, for some reason, isn’t scriptable. I do have Image floating around (not sure if it’s a standard part of the system), which can do what I want.

 1     tell application "Finder"
 2     	set sels to selection
 3     end tell
 6     repeat with sel in sels
 7     	tell application "Image Events"
 8     		set img to open sel as alias
 9     		set dims to dimensions of img
10     	end tell
12     	set cursize to "Current Size of Image: " & (first item of dims as integer as text) & " x " & (last item of dims as integer as text)
14     	display dialog cursize
15     end repeat

This gets the current size, but I’m yet to find an easy way to get input from the user, and resize it according to this. I’m sure it can’t be that tricky!

Getting all Podcast Names

Here’s a nice little AppleScript I knocked up to grab all of the details of my podcasts, for the previous post:

 1     tell application "iTunes"
 2     	set podcastList to {}
 3     	repeat with trk in selection
 4     		set thisPodcast to album of trk & " • " & artist of trk
 5     		if thisPodcast is not in podcastList then
 6     			set podcastList to podcastList & thisPodcast
 7     		end if
 8     	end repeat
 9     end tell
11     set HTML to "<ul>"
12     repeat with trk in podcastList
13     	set HTML to HTML & "<li>" & trk & "</li>"
14     end repeat
15     set the clipboard to HTML & "</ul>"

Hot Toddy • MindtripChillout Sessions 8 ★★