MagicTextarea

The following library uses jQuery to allow diferent interactions on the context of editing the value of a textarea. I recommend running these examples with Firefox 3.0+ or Chrome. Be aware that this is just the result of a weekend of work, it's still very incomplete and buggy.

Sparql variable highlight

This example detects Sparql variables (starting with a '?') from a query and highlights them in a consistent manner, it also adds mouse interaction with the highlighted variables to quickly identify all ocurrences of a certain variable within the query. Remember, the TextArea remains completely editable, try adding new variables to the query below (the query does not need to be syntactically correct, just add words that start with '?'), notice how every new variable gets a new color but reused variables maintain the one they had before. The Sparql variable highligter parser is included on the default package.
var magic = new MagicTextArea($('#sparql_textearea'));
magic.addParser(new SparqlParser());
        

A simple custom parser

Say you want to replace all ocurrences of one word by another, or highlight them as they are typed on the textarea, you can do that very easily with a custom parser. Try writting apple, lemon, banana or rainbow on the TextArea blow. Notice how the use of regular expressions allow you to easily match these strings even with different casings and/or pluralized. The parser needs to implement the parseNodeText() function, which will be called each time a portion of the textarea contents is modified. The argument holds the modified portion and it can be replaced by returning anything from a single text to a concatenation of text nodes and SPANs which can be given different css styles and behaviours. The MagicTextArea object provides functions for easy string matching, the match() function receives the text to parse, a regular expression to match words to and a callback function which must specify at least a SPAN element to be placed on top of the matching word and optionaly a DIV element to be used for mouse interactions.
var magic2 = new MagicTextArea($('#custom_textarea'));
magic2.setParsers([
    //First parser, replaces bananas by ba**nas
    {
        parseNodeText : function(text){
            return text.replace(/banana(s)?/ig, function(m){ return m[0]+m[1]+"**"+m.substring(4); });
        }
    },
    //Second parser, highlights the word 'rainbow' in different colors, Apple in red and lemon in yellow and clickable
    {
        parseNodeText : function(text){
            return magic2.match(text, /(lemon(s)?)|(apple(s)?)|(rainbow(s)?)/ig, function(w){
                var span = $('<span>'), color, tag;
                switch(w[0].toLowerCase()){
                    case 'l': //lemon(s)
                        span.css('background','yellow').html(w);
                        tag  = $('<div>').click(function(e){alert("I'm a lemon"');})
                        break;
                    case 'a': //apple(s)
                        span.css('background','red').html(w);
                        break;
                    case 'r': //rainbow(s)
                        for(var i = 0; i < w.length; i ++){
                            span.append($('<span>').css('background',get_random_color()).html(w[i]));
                        }
                        break;
                }

                var out = {span : span, tag : tag };
                return out;
            });
        }
    }
]);
        

Facebook-like semantic inline tagging

Have you ever tagged a person in a facebook post? when you type an '@' character a list is displayed to select and tag people inline directly on the textarea. The following example allows you to do exactly that. A function is provided to define this kind of behaviour. The refreshlist() function refreshes the list contents based on the text following the trigger character, the parseCaretWord() is responsible for generating the span (for the css styles) and tag (for mouse behaviours) based on the selected value from the list.
var magic3 = new MagicTextArea($('#tag_textarea'));
magic3.addInlineSuggest({
    trigger: '@',
    refreshList : function(word, list){
        list.setOptions(['Homer','Bart','Lisa','Marge']);
    },
    parseCaretWord : function(word,value){
        return {
            span : $('<span>'+value+'</span>').css('border-bottom','1px dotted blue')[0],
            tag : $('<div title="'+word+' was parsed and '+value+' was tagged">')[0]
        }
    }
});