|
An Example of Scripting Cocoa with F-Script
I have a list of a few hundred dates on the clipboard, like so:
7/26/04 7:35 PM
7/27/04 11:33 AM
7/27/04 6:34 PM
I want them in a different format, like so:
Mon Jul 26 2004 07:35:00 PM
Tue Jul 27 2004 11:33:00 AM
Tue Jul 27 2004 06:34:00 PM
Usually I pop out AppleScript at this point, but then I remembered NSDate's ability to output date strings using its little printf-style formatting language. Still, coding this in ObjC and having to create a Xcode project (or using an existing test stand) was too heavyweight. So, I thought this task is a match for F-Script.
First, I launch the F-Script toplevel app, and read the clipboard:
> datesString := (NSPasteboard generalPasteboard) stringForType:'NSStringPboardType'
Now the datesString variable holds the text of the clipboard:
> datesString
'7/26/04 7:35 PM
7/27/04 11:33 AM
7/27/04 6:34 PM'
Let's parse that into an array:
> dateStrings := datesString componentsSeparatedByString:'\r'
> dateStrings
NSCFArray {'7/26/04 7:35 PM', '7/27/04 11:33 AM', '7/27/04 6:34 PM'}
OK, we have an array of strings. Let's create a corresponding array of NSDate objects, letting NSDate do the heavy lifting of parsing the date string:
> dates := NSDate dateWithNaturalLanguageString:@dateStrings
> dates
{2004-07-26 19:35:00 -0500,
2004-07-27 11:33:00 -0500,
2004-07-27 18:34:00 -0500}
This is very interesting. Here, we're calling a Cocoa API (NSDate dateWithNaturalLanguageString:*) with an array. But this API only takes an NSString, not an array. Here, F-Script noticed the at-sign proceeding the dateStrings array, enumerates the array, calling the API once for each element, collects the output and returns a new array. Neat!
Now, let's transform our list of dates into the desired format:
> dateStringsOut := dates descriptionWithCalendarFormat:'%a %b %e %Y %I:%M:%S %p'
> dateStringsOut
{'Mon Jul 26 2004 07:35:00 PM',
'Tue Jul 27 2004 11:33:00 AM',
'Tue Jul 27 2004 06:34:00 PM'}
Another interesting thing happens here. dates is an array, but we're sending a message to it (descriptionWithCalendarFormat:) that it doesn't understand. What happens here is that F-Script steps in again and sends the message to each array element, again collecting the output for us and returning a new array.
At this point I just copied the text out of the F-Script toplevel and cleaned it up a little using BBEdit's columnar selection, but I could have carried it forward to output a string instead of an array:
> datesStringOut := dateStringsOut componentsJoinedByString:'\r'
> datesStringOut
'Mon Jul 26 2004 07:35:00 PM
Tue Jul 27 2004 11:33:00 AM
Tue Jul 27 2004 06:34:00 PM'
And popped the final result back on the clipboard:
> (NSPasteboard generalPasteboard) declareTypes:{'NSStringPboardType'} owner:nil
1564
> (NSPasteboard generalPasteboard) setString:datesStringOut forType:'NSStringPboardType'
true
Or, here's the one-liner for you perl types:
> ((NSDate dateWithNaturalLanguageString:@(((NSPasteboard generalPasteboard) stringForType:'NSStringPboardType') componentsSeparatedByString:'\r')) descriptionWithCalendarFormat:'%a %b %e %Y %I:%M:%S %p') componentsJoinedByString:'\r'
'Mon Jul 26 2004 07:35:00 PM
Tue Jul 27 2004 11:33:00 AM
Tue Jul 27 2004 06:34:00 PM'
* Actually, this is an undocumented API. One double-edged sword F-Script offers is that it's really easy to discover and use undocumented APIs -- they just popup in the code completion box!
Update: Paul Bissex offers the following Python one-liner to compare and contrast:
import time, commands; print '\n'.join([time.strftime('%a %b %d %Y %I:%M:00 %p', time.strptime(item.strip(), '%m/%d/%y %I:%M %p')) for item in commands.getoutput('pbpaste').split('\n')])
Good work, Paul. One-liners in Python are a little more tricky in Python than a whitespace-doesn't-matter language like Perl. Still, I'd give the edge to F-Script. But then, it's purpose-built to do this type of work.
Update: Fritz Anderson alerts me to the fact dateWithNaturalLanguageString: is documented. Not sure how I missed this, but there you go. However, my point about F-Script making it really easy to use undocumented methods still stands.
Thursday, September 16, 2004
12:00 AM
|