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
15     
16     
17     
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
26     
27     
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"
34              
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
53     

Scripting iTunes 7

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

artwork:

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

playlist:

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

track:
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.
 2     
 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://phobos.apple.com/WebObjects/MZSearch.woa/wa/advancedSearchResults?"
 9     
10     on run {}
11      
12      tell application "System Events"
13          try
14              get process "iTunes"
15          on error
16              return "No Track"
17          end try
18      end tell
19      
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
29      
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>"
36      
37      set theString to "<p class='itunes'> " & trackLink & " • " & artistLink & " • " & albumLink & " " & myRating(theRating) & "</p>"
38      
39      set the clipboard to theString
40      
41      tell application browser
42          activate
43          tell application "System Events" to keystroke "v" using {command down}
44      end tell
45     end run
46     
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
56     
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
67     
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, Preview.app isn’t scriptable. I do have Image Events.app 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
 4     
 5     
 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
11      
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)
13      
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
10     
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 ★★