There’s a good reason – I’ve been hauling ass. My Unity Launcher and Messaging Menu extensions have gone through several iterations, and are shaping up well. The plan is to bundle those extensions with the latest Thunderbird 5.0 beta to get some more user feedback.
The majority of my work lately has been on a project called EDS Contacts Integration. Do you remember when I talked about Ubuntu One contacts sync, and how I wanted to integrate that with Thunderbird’s address book? Well, I went to UDS a few weeks back, and I learned that a bigger / better goal would be to integrate with EDS (Evolution Data Server), which acts like the global address book, task list, calendar, etc for Ubuntu. If I integrate here, then *all* Evolution address books (including the Ubuntu One address book and Google Contacts address books) should be available in Thunderbird. So it’s a pretty big win.
So, like the Unity Launcher and Messaging Menu integration, this integration is currently being implemented as a Thunderbird add-on.
Currently, this add-on has basic read-only. I can view EDS address books, contacts and mailing lists. EDS contacts appear in the auto-complete when I start typing an e-mail address. They’re searchable. I can view the photos of EDS contacts. There are some edge cases that I haven’t addressed yet (reading address books that require authentication, for example). That’ll be coming soon.
I’ve also started work on write capabilities. I can now add and remove addresses on a mailing list, and set whether or not I want e-mail addresses to be hidden when I send mail to the list.
So, in short, I’m making pretty decent progress. Not bad for a month’s work.
But I can’t just fork over the add-on for you to play with, because this work has several other moving parts. The first moving part is the core address book de-RDF’ing work I started a few months back. The patch for this is landing in Thunderbird’s trunk shortly, which I’ve very excited about. And the second moving part: a patch in trunk where I’ve made a few slight modifications to the address book infrastructure. This makes it easier for add-ons (like my EDS integration add-on) to extend the behaviour of the address book. This will also, hopefully, be landing shortly once I’ve polished it up, and gotten it through review.
Once those patches land, my add-on should work properly on trunk. And not long after that, the patches will land in an Early Bird release for you all to try!
More blogging soon. And more screenshots. And maybe a video. Stay tuned.
So I’d hate to damage the war effort by adding more RDF code to Thunderbird.
The solution? I have to finish what Joey Minta started – at least for the address book. I have to replace all RDF-dependant code with something better – something extendable.
Then I can get down to work on the Ubuntu One sync.
So saddle up. We have to hunt this RDF bum down. For justice.
So I spent a chunk of time over the last day or so looking at prior art – the efforts of others to solve the same problem. (I’m using “prior art” pretty loosely. I’m not by any means filing patent claims.)
Prior Art Round-up
The Hedera Project
Hedera is a Thunderbird extension, and probably the most direct solution to the Thunderbird and Ubuntu One integration problem. With Hedera, all contacts in all address books are sent off to Ubuntu One, with metadata to keep the contacts in the right address books. Metadata is also included to keep contacts distinct from one Thunderbird profile to the next (if you’re one of the rare users of profiles).
As of late, the extension has gotten a bit dusty – the author, James Tait, is currently working at Canonical, and hasn’t had much time to maintain it.
Despite that, it still does the job pretty well. I was successfully able to synchronize my contacts to Ubuntu One, which made me fist-pump. Great work, James!
However, after examining the code, I have a few concerns:
The first one that jumps out at me is the reliance upon a shell script to determine the DesktopCouch server port, as well as obtain access credentials. While effective, I think a more direct approach would be more appropriate. Perhaps I could develop a DesktopCouch XPCOM service that returns these values?
Contacts that are not branded with “Thunderbird” metadata are ignored. This means that contacts created from the Ubuntu One web interface are not brought into Thunderbird, unless the metadata can somehow be added there. I didn’t immediately see a way to do this. This also means that contacts from other applications (I’m looking at you, Evolution) don’t get brought into Thunderbird.
Since the contacts are also given profile metadata, it means that I only get those contacts if I share the same profile. This is problematic if I drop my computer in the river, get a new one, and fire up a copy of Thunderbird: my profile will be different, so my contacts won’t come in. They’ll still exist in Ubuntu One’s storage, but won’t come into my Thunderbird profile, unless I modify my profile string to match my old one.
Funambol Mozilla Sync Client
Funambol develops open-source mobile communications sync software, and it looks like Canonical is using Funambol to power their mobile sync services.
Users install the Funambol Mozilla Sync Client, which then syncs contacts with Ubuntu One over the mobile sync service.
According to the support pages, only Thunderbird 2.x is currently supported. Thunderbird 3.1.9 is the current version in the Ubuntu packages, and the Mozilla Messaging team is working like crazy people on 3.3 (where did 3.2 go? long story). Supporting Thunderbird 3 is a BFD.
Now, with respect to that last point, I’m not against paying for stuff. Money lets companies like Canonical, Funambol (and Mozilla Messaging, for that matter) survive. But I do think it’s a little silly that Thunderbird needs to pretend to be a mobile phone, and communicate through the mobile sync service. That’s why I said Hedera was the more direct solution.
If I got any of that wrong, I’m sure someone from Funambol will comment and correct me.
Bindwood
Bindwood is an extension that allows Mozilla Firefox to synchronize bookmarks via Ubuntu One. The reason I’m putting this up, is because a lot of good code has been written here to communicate with the DesktopCouch service. If I resolve a few licensing issues, it might be possible for me to leverage some of that code to make the Thunderbird + Ubuntu One project move faster.
Evolution-CouchDB creates a new address book called “Ubuntu One” for every user. Any contacts that go into that address book are sync’d with Ubuntu One, and any contacts that get added to Ubuntu One get loaded into that address book.
It’s an elegant solution, and addresses the issues I brought up with Hedera.
If I were to implement a similar solution for Thunderbird, it would mean that contacts between Evolution would be seamlessly imported into Thunderbird. The behaviour would be exactly the same. Consistency is good. Consistency means happy users.
Unless I hear compelling argument for something else, I think this the behaviour I’m going to implement.
Mac OSX’s Address Book
Mac OSX has it’s own internal address book, and many Mac-based Thunderbird users were crying out for integration. A developer named Peter Van der Beken karate-kicked the bug (and may have collected a bug bounty on it…unsure), and now we have OSX address book integration.
The OSX address book integration is very similar to Evolution’s behaviour: it creates a new address book within Thunderbird, and all contacts from the OSX native address book appear there.
As it stands, this integration is read-only.
Since we’re dealing with OSX, it means Objective-C is the name of the game. Here’s the code.
Ugh. Wouldn’t it be awesome to leverage some of the work from Bindwood, Hedera (and maybe Funambol…I haven’t examined their code yet), and implement the Ubuntu One integration all in Javascript? Yes! That’d be lovely!
Except for one thing.
RDF
I spent most of yesterday examining this one, and I think I’ve got my head wrapped around it.
So, RDF stands for Resource Description Framework, and it’s a way of representing information in a way so that machines can make useful inferences and queries about that information. That’s a super-simplified definition. Here’s something a little more robust.
What does this have to do with Thunderbird and Ubuntu One?
Well, it turns out that the Thunderbird address book interface uses RDF to query / know about the address books that are available. So, when you pop open the address book manager in Thunderbird, and it populates the list of address books, it’s using RDF to get that information.
So what’s wrong with that? Well, it means that if I want to add a special “Ubuntu One” address book, it has to register itself with the RDF service as an RDFResource.
There’s two issues there:
Part of RDFResource is not scriptable, which means it’d need to be implemented in C++. So much for leveraging Bindwood / Hedera / Funambol.
The Thunderbird team knows about the limitations of RDF and are trying to remove it’s usage from Thunderbird. I’d hate to implement all that RDFResource stuff just so it can get tossed out in a few months.
So I might have to really start pushing on RDF removal from the address book. If I go that route, it means that Ubuntu One synchronization would not be available for anything earlier than Thunderbird 3.3. Ugh.
Sounds like it’s time for me to discuss this with my superiors. I’ll let you know what I find out.
I’ve been silent about my work for a few weeks, which is a shame, because one of the top reasons why I accepted a job with Mozilla Messaging was because I was free to talk about what I was doing.
I’ve been neglecting that right, but only because I’ve been holy shit busy. I’ve been blitzing my Ubuntu Unity integration work like a MoFo, and have gotten two Thunderbird extensions up on Mozilla Labs:
Ubuntu One is a service that allows you to sync things like files, bookmarks and contacts between different computers. (Incidentally, Mozilla has their own service called Sync to do something similar with bookmarks and passwords.)
That’s a pretty cool idea. Imagine it – you get a brand new computer, hook it up to Ubuntu One, and blam: all of your bookmarks and contacts are already there waiting for you.
Currently, however, Thunderbird does not support sharing contacts via Ubuntu One.
And that’s what I’m tackling next.
Ubuntu One Contacts Integration
At this point, my goal is to write an extension that will add a new address book to Thunderbird. Any contacts that are currently stored and shared via Ubuntu One will appear in that address book.
I’ll deal with adding new contacts later – for now, I’ll just do read-only, to keep the complexity down.
So stay tuned. Ubuntu One Contacts integration is coming…
I woke up after a night of fitful dreaming about long airplane rides, dip masquerading as hummus and missing socks.
I only had myself to blame for the socks. Em had awesomely helped me pack two weeks worth of clothes into a carry-on bag, and the socks had been my responsibility. Sigh. Oh well.
It was early at this point. Too early. I glanced at the bedside clock…6 AM. It’d been a long time since I’d been up this early. And yet, strangely, I felt fully rested.
Fully rested, and excited. I was in Hawaii, baby!
I was determined to make the best of the early morning, and watch the sunrise. So, I scrambled around, getting dressed – during which, I got a few shots of the sun starting to rise through my hotel room window.
It’s pretty high up. I was on the 23rd floor.24-Jan-2011 11:28, FUJIFILM FinePix A345, 2.8, 5.8mm, 0.5 sec, ISO 250
It was time to hit the pavement. I threw on my sandals, and stepped into the elevator. I tried not to think about my sock problem. I figured I would spend most of my trip in sandals, so the lack of socks really wouldn’t be an issue until later on in the trip.
The hotel was pretty close to the beach, but the sun was coming up fast, and I didn’t want to miss it. I started jogging, flew past the Hilton lagoon, and made it to the beach in time to take these shots:
It took me about 5 minutes to jog to the beach, and the sun had already come up quite a bit.24-Jan-2011 11:38, FUJIFILM FinePix A345, 2.8, 5.8mm, 0.5 sec, ISO 119
There was a rock barrier going out into the water. I walked down to the end of it for some shots, and took a video. The rocks were black, volcanic stuff.24-Jan-2011 11:41, FUJIFILM FinePix A345, 2.8, 5.8mm, 0.5 sec, ISO 129
Taken from the end of the rock barrier. That’s a catamaran boat. I rode one of those later on in the trip.24-Jan-2011 11:41, FUJIFILM FinePix A345, 2.8, 5.8mm, 0.313 sec, ISO 100
Palm trees on the beach at sunrise.24-Jan-2011 11:55, FUJIFILM FinePix A345, 2.8, 5.8mm, 0.033 sec, ISO 83
Before going back up, I took a few minutes to walk around the hotel. There was a nice decorative fountain near the entrance, as well as a Kona Coffee shop.
A decorative fountain near the hotel.24-Jan-2011 12:03, FUJIFILM FinePix A345, 2.81, 5.8mm, 0.238 sec, ISO 100
I’m not a big coffee drinker, but apparently Kona Coffee is a pretty BFD. Before I left home, my Mom asked me to bring a few bags back. I didn’t have a chance on this morning though – the Kona Coffee shop was closed:
Precious Kona coffee. It’s closed at this point, so I’d come back a few days later.24-Jan-2011 12:17, FUJIFILM FinePix A345, 2.85, 6.0mm, 0.172 sec, ISO 100
I eventually made it back to my room to grab a quick shower and shave before the 9AM breakfast.
The hotel didn’t want you to forget that either – they were pumping episodes of Hawaii Five-O through some flat-screens near reception, 24/7.
Along with the hotel rooms, the Ilikai was also providing a meeting room for the team for the week. The meeting room was also where breakfast and lunch would be served. It was a pretty awesome arrangement.
When I got to the meeting room, there were already a bunch of people there, and I went around and said a lot of hello’s. Once again, a lot of names and faces flew by, and it was hard to keep them all straight in my head.
Breakfast was yogurt with granola, and what appeared to be banana bread. Delicious.
After breakfast, David Ascher gave a talk about the mission of Mozilla Messaging, and what we’d accomplished in 2010, and what we were aiming to accomplish in 2011. There was a nice and easy, accessible vibe in the room, and I don’t think it was just because everybody was wearing Hawaiian shirts – the whole crew just seemed to gel that way.
After the talk, we more or less figured out the schedule for the rest of the week. That day, we’d be doing a bunch of demos.
Demos
The demos were pretty cool. Blake did one on the account provisioning service that he’s been working on for Thunderbird:
After that, Andrew Sutherland gave a talk on the new widgeting library he was working on called WMSY.
Afterwards, there was a big talk about mail storage with David Bienvenu – one of the original developers of Thunderbird.
After that, it was lunch break. Salad and sandwiches. Very tasty. There was also some peculiar bread that had a sweet taste and was blue/purple inside. Very interesting.
After lunch, people just hacked on their laptops for a bit, and chatted. Smaller discussions about other projects broke out. People went out onto the patio for sun. Very relaxed and casual. Eventually, someone plugged in the XBox and the Kinect, and we watched David Ascher and Dan Mosedale do some extreme white-water rafting.
Dinner at Uncle Bo’s
Eventually, things wound down. Old habits die hard, and the group started to fold around 5PM. At that point, I packed up my stuff and headed back to my room. I talked to Em on Skype. I got ready for dinner – I’d be meeting the rest of the group downstairs at 6PM.
This is the view from my hotel room. That’s the Hilton lagoon in the middle, and the beach and ocean just beyond.24-Jan-2011 13:02, FUJIFILM FinePix A345, 2.8, 5.8mm, 0.003 sec, ISO 64
I showed up at the lobby just in time for Sancus to tell me that we were meeting at 6:30PM instead of 6PM. That gave me just enough time to run around and try to grab a few photos:
I didn’t take photos during the dinner (at this point, I still didn’t know everybody, and would have felt weird photographing them), but I know Roland Tanglao did. Here are a few:
Stuffed, we cabbed back home. Some of the team was headed to a patio on the beach, and I tagged along. As some live music played, I talked school and science fiction with Andrew Sutherland and Gozer. I also found out that Gozer is a pool shark, and we decided to find a time to hit a pool hall sometime over the week.
At some point, a wave of exhaustion hit me, and I decided to head back to the hotel.
I made my way back to my room, jotted down my daily notes, and nodded off.
This was the bug I decided to tackle today. Basically, in the new add-ons manager, add-ons are listed alphabetically, regardless of their state (and by state, I mean enabled, disabled, incompatible, blocked, etc). This leads to kind of a strip-ey look for large numbers of add-ons.
What we’d like instead is to have the add-ons grouped by state, and then sorted alphabetically within that state. Here’s a mock-up by bug-reporter (and Firefox UX team member) Jennifer Boriss:
I got to work around 8:45AM this morning. Around 10:13AM, I had finished most of my introductions, had my tour, had my accounts set up, found my desk, and started work.
My approach to finding the code: I find a string in the interface that seems unique to the area I’m working in (in this case, it was “Search all add-ons”, which is found in the search text input of the add-ons manager). I did a search for that string, and it returned the file mozilla-central/toolkit/locales/en-US/chrome/mozapps/extensions/extensions.dtd.
But this only takes us half-way. Since Firefox is translated, the strings are stored separately from where they’re used. In extensions.dtd, the string I searched for is given the key “search.placeholder”.
Searching for “search.placeholder” with MXR gives me paydirt: mozilla-central/toolkit/mozapps/extensions/content/ holds the files extensions.css, extensions.js, extensions.xul and extensions.xml.
So I tool around in extensions.js a bit, reading the developer documentation, and getting to know the code. The code contains quite a few classes, including something called gViewController. Digging deeper into it, it looks like gViewController controls (brings up, shuts down) the various “views” available in the add-ons manager. Cool – so now I just need to find the view that lists the user’s add-ons.
Ah hah! Found it: gListView. gListView grabs all of the installed (or to-be-installed) add-ons, and populates the interface. So this is where the sorting needs to happen. I tested to make sure I was in the right place in the code by using dump calls to a terminal. Bonus: edits in this portion of the code do not require a full browser restart – instead, I just close and reopen the add-ons manager to see my changes. Nice!
Initially, my idea was to have 4 “buckets”, one for each of the 4 states (“enabled”, “incompatible”, “disabled”, “blocked”). I’d divide up the add-ons into those 4 buckets, and then sort each bucket, and then join the 4 buckets for the final result.
Blake came up with a better solution: the Schwartzian Transform (straight out of Space Balls, I know). The idea is that, instead of having separate buckets like before, we just go through the entire collection of add-ons, and “label” them based on what bucket they belong to. Then we sort the entire collection, giving the bucket-label a high-order sorting priority. It sounds complicated, but it actually wasn’t that difficult to code. It’s a tiny piece of code, its readable, and quite elegant. So kudos to Blake for that solution.
Anyhow, I wrote my patch. I just figured out how to run the interface tests for Firefox (they use something called Mochitest). I set those tests off on one of the fast machines in the office, packed up my gear, and headed home.
It was a solid days work. Tomorrow, I hope to write some new tests for the Schwartzian transform, and submit my patch to Bugzilla. Woop!
With the Winter holidays drawing to a close, I’m really looking forward to starting the next chapter of my life – namely, my new job at Mozilla Messaging working on the Thunderbird e-mail client.
In just a little under a week, I’ll be knee-deep in a code-base larger than any I’ve ever worked on before. And I’ll be working with some of the best software developers in the world.
So, what exactly will I be doing for Thunderbird? What project will I be starting my work with? I’m so glad you asked…
Thunderbird + Unity = Badass
Ok, that’s not technically the code-name for the project, but I think it more or less conveys my feelings about the whole thing.
So here’s the story in a nutshell:
Ubuntu Linux is one of several operating systems that Thunderbird runs on (the other big ones being Mac OSX and the various flavours of Microsoft Windows). I use Ubuntu as my primary operating system – I’m comfortable with it, and I like it.
In the coming months, there will be a tectonic shift of sorts in Ubuntu. The graphical user interface that most Ubuntu users are used to (the GNOME Shell) will no longer be the default. Instead, Canonical, the makers of Ubuntu, have created their own user interface to run on top of GNOME. That interface is called Unity, and will be made default in the Natty Narwhal release (due to come out on or around April 28th of this year).
Just to make sure we’re clear on this: Ubuntu is not dropping GNOME. The GNOME Shell is the icing on the whole GNOME Stack. Canonical has just decided to put their own icing on the cake.
So, anyhow, my job is to make Thunderbird work nicely with Unity in time for the April 28th release.
And by “work nicely”, I mean the following:
The Global Menu Bar
If you’ve never used Mac OSX, it’s likely that you don’t know what a global menu bar is. Here’s the idea: in Windows and Ubuntu, each window tends to have its own menu bar (File, Edit, etc…).
In Mac OSX, and the upcoming Unity shell, instead of having these individual menu bars, we have a single, overarching menu bar. This menu bar changes itself every time you switch application focus.
Here’s some guy demonstrating the global menu in Ubuntu Linux:
Currently, Thunderbird doesn’t “play nice” with Unity’s global menu bar, and just displays the menu within the Thunderbird window as it always has.
Ubuntu Unity also sports a shiny new messaging menu. The messaging menu aggregates all sorts of message-related information – and that includes e-mail messages, chat messages, social networking messages, etc. It tosses all of these into a nice, clean, simple notification interface, like this:
It’s up to messaging application developers to leverage this feature in Unity, and that’s where I come in. I’ll be getting Thunderbird to work nicely with this messaging menu. Click here to read more about Ubuntu Unity’s messaging menu.
The Task List
Ubuntu Unity also sports a new application launcher. The launcher is a panel that stretches down the left-hand side of the screen, and allows users to quickly find and execute their applications. It also lets users know which applications are already open. In a way, it is very similar to the Mac OSX dock.
Here is a Canonical designer demonstrating the new launcher:
Right-clicking on an item in the launcher brings up a context-menu for the selected application. For Thunderbird, we’ll probably want the context menu to allow users to do some common operations, such as fetching mail, and composing a new message. We’ll probably also want to display the number of unread messages. So that’s what I’m going to be looking into there.
I’m looking forward to tackling these problems! I’ll keep you posted on my progress.
Belated happy holidays! My last post was over a month ago, and so my blog has a nice layer of web-dust on it right now. Well, here I am to ease your mind. I’m still alive!
But that almost wasn’t true.
I won’t bore you with the details – I’ll just give you the facts, and let you fill in the blanks.
My girlfriend Em, her sister Cassie, and myself, were up in Collingwood on New Years Day, enjoying a relaxing day at a Norwegian spa (the outdoor baths were amazing – how awesome is it to be in a boiling hot tub, while simultaneously, your hair is so frozen that it’s snapping off in your hands?)
The roads that night were treacherous. Snowy, un-plowed, and dark. I had borrowed my Mom’s car for the trip, and we took it realllllly slow.
After a tortoise-paced two hour ride back to Em’s place in Newmarket, and then another two hour drive from Newmarket to my home in Grimsby the next day, I was getting pretty sick of winter driving. On top of that, the brakes seemed to be acting funny. I found myself sliding a lot, and there didn’t seem to be a lot of resistance when I put my foot down.
The next day, my Mom takes the car to go to work. She doesn’t even leave the drive-way. The brakes hadn’t been acting funny: the brakes hadn’t been acting at all. Turns out we had a leaky brake-line for the entire trip…
Guts of the story: I think we drove home from Collingwood with about 35% brake power in one of the worst snow storms I’ve ever driven in.
Breakfast tasted especially good for us that morning.
Anyhow, now where was I? Oh yeah…
MarkUs
MarkUs 0.6 got kicked out a week or so ago. The MarkUs Team kicked the crap out of a bunch of tickets over the holidays, and I think we ended up with a pretty solid release. MarkUs is being used again at UofT this semester, and Byron Weber Becker is also piloting it at UWaterloo. I’ll cautiously say that things seem to be going well for this release. Great job, MarkUs Team!
I’m TAing the students working on MarkUs for Greg’sUCOSP course again. We had a fantastic code-sprint this past weekend! The new team members have already started working on tickets and submitting code to review. I think we’re on our way into another highly productive semester.
This is a pretty dead-simple code review tool that came about during a Rails Rumble a few months back. It has that “big friendly buttons and round corners” web 2.0 thingy going on. I haven’t gone so far as to actually try it out, but I did watch this web-cast:
Not bad if you just want to get your code out there, and get your team commenting on your changes…
A few things caught my attention:
It’s a web service, so you don’t install it…you sign up for it
It currently only supports Git.
There doesn’t seem to be any support for contextual per-line commenting…I think it’s just file by file commenting. I’d love it if I could comment on a single line of code…
Still, if I was working on a project hosted on a Git repo, and I needed a dead-simple code review service, and I needed it quickly, I could probably do a lot worse than this.
Remember that time when I wrote about how it might be neat if somebody created a code review tool on top of Google Wave? (or Bespin for that matter – though I didn’t mention it, and should have)
Anyhow, looks like something Wave-ish (yet simpler, more streamlined) has been developed. Check out Squad.
I just tried this thing out for free (with ads, features locked, etc), and it was pretty cool. I could see something like this being very useful for showing new MarkUs team members how to do things. Actually, I just used it to show a new member of the MarkUs team how to use Shoulda. Pretty useful. It sure beats coding through IRC and Pastie.org.
A few things to keep in mind:
Super simple to get going – open up a session, and send someone a generated link, and you’re both coding in no time
One person codes at a time…so while one person edits, the screen is locked for everyone else
Ads on the left are a little annoying
Sports syntax highlighting for a number of languages – though I noticed that Ruby wasn’t one of them. :/
I can see this becoming second nature, like Pastie.org.
Who knows – I might find more reasons to use Squad as the semester rolls, and MarkUs picks up speed. I’ll keep you posted.
This service crowd-sources code review requests, so don’t expect to get deep architectural feedback, because it’ll probably come from strangers who don’t/barely know your code base.
The idea is – slap a piece of code that you’d like refactored up on the site, and then others swoop in with brilliant suggestions (assuming of course, you asked your question properly…check this out…what the…?)
This is the sort of thing that CS instructors probably wouldn’t want their students using too much…it’d then become solve-my-CS-programming-assignment.com.
Still, I think it counts as peer code review. And it’s way different that anything else I’ve been looking at. Nice.
So, if you recall, I was asked to write a Firefox extension that would do word counting on websites.
Originally, when I started this project, I set a goal for myself: I copied the text from Project Gutenberg’s First Folio version of Shakespeare’s Hamlet into OpenOffice Writer, recorded the word/line/character count statistics, and set that as my projected goal for my first iteration of my extension.
But there’s a problem with this approach: I’m supposed to be copying the behaviour of Unix’s wc, not OpenOffice Writer’s word count. Normally, this wouldn’t be a problem – a word count is a word count, a line count is a line count, and Writer should pump out the same numbers as wc.
Not so.
In my last post, I wrote:
According to OpenOffice Writer, this text has 32230 words, 173543 characters, and 4257 lines.
However, upon passing the same text (saved in the textfile “count.txt”) through wc, I got the following output:
5302 32230 178845 count.txt
Writer and wc agree on the number of words, but disagree on the number of lines – 5302 (wc) vs 4257 (Writer). It’s a disagreement of about a thousand lines.
Brutal.
Anyhow, I’m going to focus on wc’s approach to line counting – simply returning the number of newline characters in the file.
And guess what…it works. For Hamlet, my extension pumps out:
Document statistics:
Word Count: 32230
Line Count: 5302
Character Count: 178845
Character Count (no spaces): 142368
Nice.
Hamlet’s just the simple case though. There are plenty of other cases to consider, but this is a start.
In this version, I’m using Mozilla’s TreeWalker implementation to stitch together the page text. So far it seems to be working alright, but if it somehow ends up falling through, I might end up using something like Andrew Trusty’s code with the jQuery library to do the text stitching.
So there it is. Maybe I’ll keep working on this, pretty it up a bit, etc. However, work starts on Monday, and that’ll probably take up most of my technical attention.
The dragon cave!23-Jun-2009 11:55, FUJIFILM FinePix A345, 2.8, 5.8mm, 0.033 sec, ISO 272
NOTICE
Persons attempting to find a motive in this narrative will be prosecuted; persons attempting to find a moral in it will be banished; persons attempting to find a plot in it will be shot.
By order of the author,
Per G. G., Chief of Ordinance