/* =============================================================================== Chili is the jQuery code highlighter plugin ............................................................................... Copyright 2007 / Andrea Ercolino ------------------------------------------------------------------------------- LICENSE: http://www.opensource.org/licenses/mit-license.php WEBSITE: http://noteslog.com/chili/ =============================================================================== =============================================================================== Metaobjects is the jQuery metadata plugin on steroids ............................................................................... Copyright 2007 / Andrea Ercolino ------------------------------------------------------------------------------- LICENSE: http://www.opensource.org/licenses/mit-license.php WEBSITE: http://noteslog.com/metaobjects/ =============================================================================== */ //----------------------------------------------------------------------------- ( function($) { ChiliBook = { //implied global version: "1.8b" // 2007-05-26 , automatic: true , automaticSelector: "code" , codeLanguage: function( el ) { var recipeName = $( el ).attr( "class" ); return recipeName ? recipeName : ''; } , metadataSelector: "object.chili" // use an empty string for not executing , recipeLoading: true , recipeFolder: "" // used like: recipeFolder + recipeName + '.js' , stylesheetLoading: true , stylesheetFolder: "" // used like: stylesheetFolder + recipeName + '.css' , defaultReplacement: '$$' , replaceSpace: " " // use an empty string for not replacing , replaceTab: "    " // use an empty string for not replacing , replaceNewLine: " 
" // use an empty string for not replacing , recipes: {} //repository , queue: {} //register //fix for IE: copy of PREformatted text strips off all html, losing newlines , preFixCopy: document.selection && document.selection.createRange , preContent: "" , preElement: null }; $.metaobjects = function( options ) { options = $.extend( { context: document , clean: true , selector: 'object.metaobject' }, options ); function jsValue( value ) { eval( 'value = ' + value + ";" ); return value; } return $( options.selector, options.context ) .each( function() { var settings = { target: this.parentNode }; $( '> param[@name=metaparam]', this ) .each( function() { $.extend( settings, jsValue( this.value ) ); } ); $( '> param', this ) .not( '[@name=metaparam]' ) .each( function() { var name = this.name, value = jsValue( this.value ); $( settings.target ) .each( function() { this[ name ] = value; } ); } ); if( options.clean ) { $( this ).remove(); } } ); }; $.fn.chili = function( options ) { var book = $.extend( {}, ChiliBook, options || {} ); function cook( ingredients, recipe ) { function prepareStep( stepName, step ) { var exp = ( typeof step.exp == "string" ) ? step.exp : step.exp.source; steps.push( { stepName: stepName , exp: "(" + exp + ")" , length: 1 // add 1 to account for the newly added parentheses + (exp // count number of submatches in here .replace( /\\./g, "%" ) // disable any escaped character .replace( /\[.*?\]/g, "%" ) // disable any character class .match( /\((?!\?)/g ) // match any open parenthesis, not followed by a ? || [] // make sure it is an empty array if there are no matches ).length // get the number of matches , replacement: (step.replacement) ? step.replacement : book.defaultReplacement } ); } // function prepareStep( stepName, step ) function knowHow() { var prevLength = 0; var exps = new Array; for (var i = 0; i < steps.length; i++) { var exp = steps[ i ].exp; // adjust backreferences exp = exp.replace( /\\\\|\\(\d+)/g, function( m, aNum ) { return !aNum ? m : "\\" + ( prevLength + 1 + parseInt( aNum, 10 ) ); } ); exps.push( exp ); prevLength += steps[ i ].length; } var source = exps.join( "|" ); return new RegExp( source, (recipe.ignoreCase) ? "gi" : "g" ); } // function knowHow() function escapeHTML( str ) { return str.replace( /&/g, "&" ).replace( / 1 ) { return; } var ingredients = el.childNodes[0] && el.childNodes[0].data; if( ! ingredients ) { return; } // hack for IE: \r is used instead of \n ingredients = ingredients.replace(/\r\n?/g, "\n"); var dish = cook( ingredients, recipe ); // all happens here if( book.replaceTab ) { dish = dish.replace( /\t/g, book.replaceTab ); } if( book.replaceNewLine ) { dish = dish.replace( /\n/g, book.replaceNewLine ); } $( el ).html( dish ); if( ChiliBook.preFixCopy ) { $( el ) .parents() .filter( "pre" ) .bind( "mousedown", function() { ChiliBook.preElement = this; } ) .bind( "mouseup", function() { if( ChiliBook.preElement == this ) { ChiliBook.preContent = document.selection.createRange().htmlText; } } ) ; } } // function makeDish( el ) function getPath( recipeName, options ) { var settingsDef = { recipeFolder: book.recipeFolder , recipeFile: recipeName + ".js" , stylesheetFolder: book.stylesheetFolder , stylesheetFile: recipeName + ".css" }; var settings; if( options && typeof options == "object" ) { settings = $.extend( settingsDef, options ); } else { settings = settingsDef; } return { recipe : settings.recipeFolder + settings.recipeFile , stylesheet: settings.stylesheetFolder + settings.stylesheetFile }; } //function getPath( recipeName, options ) //----------------------------------------------------------------------------- // initializations if( book.metadataSelector ) { $.metaobjects( { context: this, selector: book.metadataSelector } ); } //----------------------------------------------------------------------------- // the coloring starts here this .each( function() { var el = this; var recipeName = book.codeLanguage( el ); if( '' != recipeName ) { var path = getPath( recipeName, el.chili ); if( book.recipeLoading || el.chili ) { /* dynamic setups come here */ if( ! book.queue[ path.recipe ] ) { /* this is a new recipe to download */ try { book.queue[ path.recipe ] = [ el ]; $.getJSON( path.recipe, function( recipeLoaded ) { recipeLoaded.path = path.recipe; book.recipes[ path.recipe ] = recipeLoaded; if( book.stylesheetLoading ) { checkCSS( path.stylesheet ); } var q = book.queue[ path.recipe ]; for( var i = 0, iTop = q.length; i < iTop; i++ ) { makeDish( q[ i ], path.recipe ); } } ); } catch( recipeNotAvailable ) { alert( "the recipe for '" + recipeName + "' was not found in '" + path.recipe + "'" ); } } else { /* not a new recipe, so just enqueue this element */ book.queue[ path.recipe ].push( el ); } /* a recipe could have been already downloaded */ makeDish( el, path.recipe ); } else { /* static setups come here */ makeDish( el, path.recipe ); } } } ); return this; //----------------------------------------------------------------------------- }; //main $( function() { if( ChiliBook.automatic ) { if( ChiliBook.elementPath ) { //preserve backward compatibility ChiliBook.automaticSelector = ChiliBook.elementPath; if( ChiliBook.elementClass ) { ChiliBook.codeLanguage = function ( el ) { var selectClass = new RegExp( "\\b" + ChiliBook.elementClass + "\\b", "gi" ); var elClass = $( el ).attr( "class" ); if( ! elClass ) { return ''; } var recipeName = $.trim( elClass.replace( selectClass, "" ) ); return recipeName; }; } } $( ChiliBook.automaticSelector ).chili(); } if( ChiliBook.preFixCopy ) { function preformatted( text ) { if( '' == text ) { return ""; } do { var newline_flag = (new Date()).valueOf(); } while( text.indexOf( newline_flag ) > -1 ); text = text.replace( /\]*?\>/ig, newline_flag ); var el = document.createElement( '
' );
			el.innerHTML = text;
			text = el.innerText.replace( new RegExp( newline_flag, "g" ), '\r\n' );
			return text;
		}

		$( "body" )
		.bind( "copy", function() {
			if( '' != ChiliBook.preContent ) {
				window.clipboardData.setData( 'Text', preformatted( ChiliBook.preContent ) );
				event.returnValue = false;
			}
		} )
		.bind( "mousedown", function() {
			ChiliBook.preContent = "";
		} )
		.bind( "mouseup", function() {
			ChiliBook.preElement = null;
		} )
		;
	}

} );

} ) ( jQuery );