(function($) {
  var screen, input, spinner_id, resultPrompt;
  var spinner = "<div id='%s' style='background: url(%i) no-repeat 0 center; "+
    "vertical-align: middle;'> &nbsp;</div>";

  // Options:
  // * prompt: html string to use as prompt
  // * resultPrompt: html string before each result
  // * loop: function to handle eval and logging of its result,
  //     default is $.repl.loop
  // * spinner: location of spinner image
  // * startMessage: function which returns string to display when starting repl
  $.fn.repl = function(options) {
    options = $.extend({
      prompt: '&gt;&gt; ',
      resultPrompt: '=> ',
      loop: $.repl.loop,
      spinner: 'spinner.gif',
      startMessage:  function() {
        return '# New repl.js session using jQuery '+$().jquery;
      }
    }, options);

    input = $(this);
    input.addClass('repl_input');
    resultPrompt = options.resultPrompt;
    var input_id = this.selector.replace(/^#/, '');
    spinner_id = input_id + '_spinner';
    spinner = spinner.replace('%s', spinner_id);
    spinner = spinner.replace('%i', options.spinner);

    var prompt_id = input_id + '_prompt';
    if (!$('#'+prompt_id).length) {
      input.before('<span id="'+prompt_id+'"></span>');
    }
    var screen_id = input_id + '_screen';
    $('#'+prompt_id).html(options.prompt).
      before("<div id='"+ screen_id +"'></div>");
    screen = $('#'+screen_id);

    $.repl.log(options.startMessage());
    input.focus();
    input.parent('form').submit(function() {
      var line = input.val();
      $.repl.log(options.prompt + line + spinner);
      options.loop(line);
      input.val("").focus();
      return false;
    });
    if ($.hotkeys) {
      input.bind('keydown', 'ctrl+l', function() { screen.html(''); });
    }

    return this;
  };

  $.repl = {
    version: '0.1.0',
    log: function(str) {
      screen.append(str + "<br>");
      return $('body').scrollTop($('body').attr('scrollHeight'));
    },
    logResult: function(str) {
      $('#'+spinner_id).remove();
      return $.repl.log(str);
    },
    eval: function(input) {
      try { var result = eval(input); }
      catch(e) { var result = e.name + ': '+ e.message; }
      if (typeof(result) == 'undefined') {
        result = 'undefined';
      } else {
        result = result ? result.toString() : '';
        result = $('<div/>').text(result).html();
      }
      return result;
    },
    loop: function(line) {
      var result = resultPrompt + $.repl.eval(line);
      return $.repl.logResult(result);
    }
  };
})(jQuery);

@@ -1406,16 +1406,44 @@
 d);%0A%0A   
+ if (options.startMessage) %7B
  $.repl.
@@ -1470,16 +1470,18 @@
 sage());
+ %7D
 %0A    inp

startMessage option is optional