Wednesday, June 17, 2009

More complicated JavaScript string tokenizer – and Twitter Conversations

(I'm not sure when I started using the term tokenizer - "formatter" may be more common...)

I’ve experimented in the past with a C# string.Format() alternative that would allow property names as tokens rather than the numeric index based tokens that string.Format() uses.  Hardly a unique approach, and many others did it better.

Here’s another first-draft ‘tokenizer’, this time in JavaScript:

String.prototype.format = function(tokens) {
///This is an extension method for strings, using string or numeric tokens (e.g. {foo} or {0}) to format the string.
///<param name="tokens">One or more replacement values
///if a single object is passed, expects to match tokens with object property names, 
///if a single string, number or boolean, replaces any and all tokens with the string
///if multiple arguments are passed, replaces numeric tokens with the arguments, in the order passed
///<returns>the string with matched tokens replaced</returns>
  var text = this;
  try  {
    switch (arguments.length) {
      case 0: {
        return this;
      case 1: 
        switch (typeof tokens) {
          case "object":
            //loop through all the properties in the object and replace tokens matching the names
            var token;
            for (token in tokens) {
              if (!tokens.hasOwnProperty(token) || typeof tokens[token] === 'function') {
              text = text.replace(new RegExp("\\{" + token + "\\}", "gi"), tokens[token])
            return text;
        case "string":
        case "number":
        case "boolean":
            return text.replace(/{[a-z0-9]*}/gi, tokens.toString());
            return text;
        //if multiple parameters, assume numeric tokens, where each number matches the argument position
        for (var i = 0; i < arguments.length; i++) {
          text = text.replace(new RegExp("\\{" + i + "\\}", "gi"), arguments[i].toString());
        return text;
  } catch (e) {
    return text;

The comment (in VS Intellisense format) is pretty self-explanatory, note that it doesn’t allow any special formatting as String.Format does, nor does it even support escaping {}‘s – in general it is quite crude.

That said, when used within it’s limitations it works - below are a couple of actual usage scenarios, both from my ongoing Twitter Conversations experiment:

var url = "{p1}+to:{p2}+OR+from:{p2}+to:{p1}&since={d1}&until={d2}&rpp=50".format({ 
  p1: $("#p1").attr("value"), 
  p2: $("#p2").attr("value"),
  d1: $("#d1alt").attr("value"), 
  d2: $("#d2alt").attr("value")


$.getJSON(url + "&callback=?", function(data) {
  $.each(data.results, function(i, result) {
    content = ' \
<p> \
	<a href="{from_user}"><img src="{profile_image_url}" />{from_user}</a> \
	(<a href="{from_user}/statuses/{id}">{created_at}</a>): \
	{text} \

The working Twitter Conversations sample is here, as you can tell it’s really just a wrapper around the Twitter Search API.

Labels: , , ,


Post a Comment

<< Home