| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708 | /*===============================================================================Chili is the jQuery code highlighter plugin...............................................................................LICENSE: http://www.opensource.org/licenses/mit-license.phpWEBSITE: http://noteslog.com/chili/											   Copyright 2008 / Andrea Ercolino===============================================================================*/( function($) {ChiliBook = { //implied global	  version:            "2.2" // 2008-07-06// options --------------------------------------------------------------------	, automatic:          true	, automaticSelector:  "code"	, lineNumbers:        !true	, codeLanguage:       function( el ) {		var recipeName = $( el ).attr( "class" );		return recipeName ? recipeName : '';	}	, recipeLoading:      true	, recipeFolder:       "" // used like: recipeFolder + recipeName + '.js'	// IE and FF convert   to " ", Safari and Opera do not	, replaceSpace:       " "	, replaceTab:         "    "	, replaceNewLine:     " <br/>"	, selectionStyle:     [ "position:absolute; z-index:3000; overflow:scroll;"						  , "width:16em;"						  , "height:9em;"						  , "border:1px solid gray;"						  , "padding:15px;"						  , "background-color:yellow;"						  ].join( ' ' )// ------------------------------------------------------------- end of options	, defaultReplacement: '<span class="$0">$$</span>' // TODO: make this an option again	, recipes:            {} //repository	, queue:              {} //registry	, unique:             function() {		return (new Date()).valueOf();	}};$.fn.chili = function( options ) {	var book = $.extend( {}, ChiliBook, options || {} );	function cook( ingredients, recipe, blockName ) {		function prepareBlock( recipe, blockName ) {			var steps = [];			for( var stepName in recipe[ blockName ] ) {				steps.push( prepareStep( recipe, blockName, stepName ) );			}			return steps;		} // prepareBlock		function prepareStep( recipe, blockName, stepName ) {			var step = recipe[ blockName ][ stepName ];			var exp = ( typeof step._match == "string" ) ? step._match : step._match.source;			return {				recipe: recipe				, blockName: blockName				, 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._replace ? step._replace : book.defaultReplacement			};		} // prepareStep			function knowHow( steps ) {			var prevLength = 1;			var exps = [];			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 prolog = '((?:\\s|\\S)*?)';			var epilog = '((?:\\s|\\S)+)';			var source = '(?:' + exps.join( "|" ) + ')';			source = prolog + source + '|' + epilog;			return new RegExp( source, recipe._case ? "g" : "gi" );		} // knowHow		function escapeHTML( str ) {			return str.replace( /&/g, "&" ).replace( /</g, "<" );		} // escapeHTML		function replaceSpaces( str ) {			return str.replace( / +/g, function( spaces ) {				return spaces.replace( / /g, replaceSpace );			} );		} // replaceSpaces		function filter( str ) {			str = escapeHTML( str );			if( replaceSpace ) {				str = replaceSpaces( str );			}			return str;		} // filter		function applyRecipe( subject, recipe ) {			return cook( subject, recipe );		} // applyRecipe		function applyBlock( subject, recipe, blockName ) {			return cook( subject, recipe, blockName );		} // applyBlock		function applyStep( subject, recipe, blockName, stepName ) {			var replaceSpace       = book.replaceSpace;			var step = prepareStep( recipe, blockName, stepName );			var steps = [step];			var perfect = subject.replace( knowHow( steps ), function() {				return chef.apply( { steps: steps }, arguments );			} );			return perfect;		} // applyStep		function applyModule( subject, module, context ) {			if( ! module ) {				return filter( subject );			}			var sub = module.split( '/' );			var recipeName = '';			var blockName  = '';			var stepName   = '';			switch( sub.length ) {				case 1:					recipeName = sub[0];					break;				case 2:					recipeName = sub[0]; blockName = sub[1];					break;				case 3:					recipeName = sub[0]; blockName = sub[1]; stepName = sub[2];					break;				default:					return filter( subject );			}			function getRecipe( recipeName ) {				var path = getPath( recipeName );				var recipe = book.recipes[ path ];				if( ! recipe ) {					throw {msg:"recipe not available"};				}				return recipe;			}			try {				var recipe;				if ( '' == stepName ) {					if ( '' == blockName ) {						if ( '' == recipeName ) {							//nothing to do						}						else { // ( '' != recipeName )							recipe = getRecipe( recipeName );							return applyRecipe( subject, recipe );						}					}					else { // ( '' != blockName )						if( '' == recipeName ) {							recipe = context.recipe;						}						else {							recipe = getRecipe( recipeName );						}						if( ! (blockName in recipe) ) {							return filter( subject );						}						return applyBlock( subject, recipe, blockName );					}				}				else { // ( '' != stepName )					if( '' == recipeName ) {						recipe = context.recipe;					}					else {						recipe = getRecipe( recipeName );					}					if( '' == blockName ) {						blockName = context.blockName;					}					if( ! (blockName in recipe) ) {						return filter( subject );					}					if( ! (stepName in recipe[blockName]) ) {						return filter( subject );					}					return applyStep( subject, recipe, blockName, stepName );				}			}			catch( e ) {				if (e.msg && e.msg == "recipe not available") {					var cue = 'chili_' + book.unique();					if( book.recipeLoading ) {						var path = getPath( recipeName );						if( ! book.queue[ path ] ) {							/* this is a new recipe to download */							try {								book.queue[ path ] = [ {cue: cue, subject: subject, module: module, context: context} ];								$.getJSON( path, function( recipeLoaded ) {									book.recipes[ path ] = recipeLoaded;									var q = book.queue[ path ];									for( var i = 0, iTop = q.length; i < iTop; i++ ) {										var replacement = applyModule( q[ i ].subject, q[ i ].module, q[ i ].context );										if( book.replaceTab ) {											replacement = replacement.replace( /\t/g, book.replaceTab );										}										if( book.replaceNewLine ) {											replacement = replacement.replace( /\n/g, book.replaceNewLine );										}										$( '#' + q[ i ].cue ).replaceWith( replacement );									}								} );							}							catch( recipeNotAvailable ) {								alert( "the recipe for '" + recipeName + "' was not found in '" + path + "'" );							}						}						else {							/* not a new recipe, so just enqueue this element */							book.queue[ path ].push( {cue: cue, subject: subject, module: module, context: context} );						}						return '<span id="' + cue + '">' + filter( subject ) + '</span>';					}					return filter( subject );				}				else {					return filter( subject );				}			}		} // applyModule		function addPrefix( prefix, replacement ) {			var aux = replacement.replace( /(<span\s+class\s*=\s*(["']))((?:(?!__)\w)+\2\s*>)/ig, "$1" + prefix + "__$3" );			return aux;		} // addPrefix		function chef() {			if (! arguments[ 0 ]) {				return '';			}			var steps = this.steps;			var i = 0;  // iterate steps			var j = 2;	// iterate chef's arguments			var prolog = arguments[ 1 ];			var epilog = arguments[ arguments.length - 3 ];			if (! epilog) {				var step;				while( step = steps[ i++ ] ) {					var aux = arguments; // this unmasks chef's arguments inside the next function					if( aux[ j ] ) {						var replacement = '';						if( $.isFunction( step.replacement ) ) {							var matches = []; //Array.slice.call( aux, j, step.length );							for (var k = 0, kTop = step.length; k < kTop; k++) {								matches.push( aux[ j + k ] );							}							matches.push( aux[ aux.length - 2 ] );							matches.push( aux[ aux.length - 1 ] );							replacement = step.replacement								.apply( { 									x: function() { 										var subject = arguments[0];										var module  = arguments[1];										var context = { 											  recipe:    step.recipe											, blockName: step.blockName 										};										return applyModule( subject, module, context );									} 								}, matches );						}						else { //we expect step.replacement to be a string							replacement = step.replacement								.replace( /(\\\$)|(?:\$\$)|(?:\$(\d+))/g, function( m, escaped, K ) {									if( escaped ) {       /* \$ */ 										return "$";									}									else if( !K ) {       /* $$ */ 										return filter( aux[ j ] );									}									else if( K == "0" ) { /* $0 */ 										return step.stepName;									}									else {                /* $K */										return filter( aux[ j + parseInt( K, 10 ) ] );									}								} );						}						replacement = addPrefix( step.recipe._name, replacement );						return filter( prolog ) + replacement;					} 					else {						j+= step.length;					}				}			}			else {				return filter( epilog );			}		} // chef		if( ! blockName ) {			blockName = '_main';			checkSpices( recipe );		}		if( ! (blockName in recipe) ) {			return filter( ingredients );		}		var replaceSpace = book.replaceSpace;		var steps = prepareBlock( recipe, blockName );		var kh = knowHow( steps );		var perfect = ingredients.replace( kh, function() {			return chef.apply( { steps: steps }, arguments );		} );		return perfect;	} // cook	function loadStylesheetInline( sourceCode ) { 		if( document.createElement ) { 			var e = document.createElement( "style" ); 			e.type = "text/css"; 			if( e.styleSheet ) { // IE 				e.styleSheet.cssText = sourceCode; 			}  			else { 				var t = document.createTextNode( sourceCode ); 				e.appendChild( t ); 			} 			document.getElementsByTagName( "head" )[0].appendChild( e ); 		} 	} // loadStylesheetInline				function checkSpices( recipe ) {		var name = recipe._name;		if( ! book.queue[ name ] ) {			var content = ['/* Chili -- ' + name + ' */'];			for (var blockName in recipe) {				if( blockName.search( /^_(?!main\b)/ ) < 0 ) {					for (var stepName in recipe[ blockName ]) {						var step = recipe[ blockName ][ stepName ];						if( '_style' in step ) {							if( step[ '_style' ].constructor == String ) {								content.push( '.' + name + '__' + stepName + ' { ' + step[ '_style' ] + ' }' );							}							else {								for (var className in step[ '_style' ]) {									content.push( '.' + name + '__' + className + ' { ' + step[ '_style' ][ className ] + ' }' );								}							}						}					}				}			}			content = content.join('\n');			loadStylesheetInline( content );			book.queue[ name ] = true;		}	} // checkSpices	function askDish( el ) {		var recipeName = book.codeLanguage( el );		if( '' != recipeName ) {			var path = getPath( recipeName );			if( book.recipeLoading ) {				/* dynamic setups come here */				if( ! book.queue[ path ] ) {					/* this is a new recipe to download */					try {						book.queue[ path ] = [ el ];						$.getJSON( path, function( recipeLoaded ) {							book.recipes[ path ] = recipeLoaded;							var q = book.queue[ path ];							for( var i = 0, iTop = q.length; i < iTop; i++ ) {								makeDish( q[ i ], path );							}						} );					}					catch( recipeNotAvailable ) {						alert( "the recipe for '" + recipeName + "' was not found in '" + path + "'" );					}				}				else {					/* not a new recipe, so just enqueue this element */					book.queue[ path ].push( el );				}				/* a recipe could have been already downloaded */				makeDish( el, path ); 			}			else {				/* static setups come here */				makeDish( el, path );			}		}	} // askDish	function makeDish( el, recipePath ) {		var recipe = book.recipes[ recipePath ];		if( ! recipe ) {			return;		}		var $el = $( el );		var ingredients = $el.text();		if( ! ingredients ) {			return;		}		//fix for msie: \r (13) is used instead of \n (10)		//fix for opera: \r\n is used instead of \n		ingredients = ingredients.replace(/\r\n?/g, "\n");		//reverse fix for safari: msie, mozilla and opera render the initial \n		if( $el.parent().is('pre') ) {			if( ! $.browser.safari ) {				ingredients = ingredients.replace(/^\n/g, "");			}		}		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.innerHTML = dish; //much faster than $el.html( dish );		//tried also the function replaceHtml from http://blog.stevenlevithan.com/archives/faster-than-innerhtml		//but it was not faster nor without sideffects (it was not possible to count spans into el)		//opera and safari select PRE text correctly 		if( $.browser.msie || $.browser.mozilla ) {			enableSelectionHelper( el );		}		var $that = $el.parent();		var classes = $that.attr( 'class' );		var ln = /ln-(\d+)-([\w][\w\-]*)|ln-(\d+)|ln-/.exec( classes );		if( ln ) {			addLineNumbers( el );			var start = 0;			if( ln[1] ) {				start = parseInt( ln[1], 10 );				var $pieces = $( '.ln-' + ln[1] + '-' + ln[2] );				var pos = $pieces.index( $that[0] );				$pieces.slice( 0, pos ).each( function() {					start += $( this ).find( 'li' ).length;				} );			}			else if( ln[3] ) {				start = parseInt( ln[3], 10 );			}			else {				start = 1;			}			$el.find( 'ol' )[0].start = start;			$('body').width( $('body').width() - 1 ).width( $('body').width() + 1 );		}		else if( book.lineNumbers ) {			addLineNumbers( el );		}	} // makeDish	function enableSelectionHelper( el ) {		var element = null;		$( el )		.parents()		.filter( "pre" )		.bind( "mousedown", function() {			element = this;			if( $.browser.msie ) {				document.selection.empty();			}			else {				window.getSelection().removeAllRanges();			}		} )		.bind( "mouseup", function( event ) {			if( element && (element == this) ) {				element = null;				var selected = '';				if( $.browser.msie ) {					selected = document.selection.createRange().htmlText;					if( '' == selected ) { 						return;					}					selected = preserveNewLines( selected );					var container_tag = '<textarea style="STYLE">';				}				else {					selected = window.getSelection().toString(); //opera doesn't select new lines					if( '' == selected ) {						return;					}					selected = selected						.replace( /\r/g, '' )						.replace( /^# ?/g, '' )						.replace( /\n# ?/g, '\n' )					;					var container_tag = '<pre style="STYLE">';				}				var $container = $( container_tag.replace( /\bSTYLE\b/, ChiliBook.selectionStyle ) )					.appendTo( 'body' )					.text( selected )					.attr( 'id', 'chili_selection' )					.click( function() { $(this).remove(); } )				;				var top  = event.pageY - Math.round( $container.height() / 2 ) + "px";				var left = event.pageX - Math.round( $container.width() / 2 ) + "px";				$container.css( { top: top, left: left } );				if( $.browser.msie ) {//					window.clipboardData.setData( 'Text', selected ); //I couldn't find anything similar for Mozilla					$container[0].focus();					$container[0].select();				}				else {					var s = window.getSelection();					s.removeAllRanges();					var r = document.createRange();					r.selectNodeContents( $container[0] );					s.addRange( r );				}			}		} )		;	} // enableSelectionHelper	function getPath( recipeName ) {		return book.recipeFolder + recipeName + ".js";	} // getPath	function getSelectedText() {		var text = '';		if( $.browser.msie ) {			text = document.selection.createRange().htmlText;		}		else {			text = window.getSelection().toString();		}		return text;	} // getSelectedText	function preserveNewLines( html ) {		do { 			var newline_flag = ChiliBook.unique();		}		while( html.indexOf( newline_flag ) > -1 );		var text = '';		if (/<br/i.test(html) || /<li/i.test(html)) {			if (/<br/i.test(html)) {				html = html.replace( /\<br[^>]*?\>/ig, newline_flag );			}			else if (/<li/i.test(html)) {				html = html.replace( /<ol[^>]*?>|<\/ol>|<li[^>]*?>/ig, '' ).replace( /<\/li>/ig, newline_flag );			}			var el = $( '<pre>' ).appendTo( 'body' ).hide()[0];			el.innerHTML = html;			text = $( el ).text().replace( new RegExp( newline_flag, "g" ), '\r\n' );			$( el ).remove();		}		return text;	} // preserveNewLines	function addLineNumbers( el ) {		function makeListItem1( not_last_line, not_last, last, open ) {			var close = open ? '</span>' : '';			var aux = '';			if( not_last_line ) {				aux = '<li>' + open + not_last + close + '</li>';			}			else if( last ) {				aux = '<li>' + open + last + close + '</li>';			}			return aux;		} // makeListItem1		function makeListItem2( not_last_line, not_last, last, prev_li ) {			var aux = '';			if( prev_li ) {				aux = prev_li;			}			else {				aux = makeListItem1( not_last_line, not_last, last, '' )			}			return aux;		} // makeListItem2		var html = $( el ).html();		var br = /<br>/.test(html) ? '<br>' : '<BR>';		var empty_line = '<li>' + book.replaceSpace + '</li>';		var list_items = html			//extract newlines at the beginning of a span			.replace( /(<span [^>]+>)((?:(?: |\xA0)<br>)+)(.*?)(<\/span>)/ig, '$2$1$3$4' ) // I don't know why <span .*?> does not work here			//transform newlines inside of a span			.replace( /(.*?)(<span .*?>)(.*?)(?:<\/span>(?: |\xA0)<br>|<\/span>)/ig,       // but here it does				function( all, before, open, content ) {					if (/<br>/i.test(content)) {						var pieces = before.split( br );						var lastPiece = pieces.pop();						before = pieces.join( br );						var aux = (before ? before + br : '') //+ replace1( lastPiece + content, open );							+ (lastPiece + content).replace( /((.*?)(?: |\xA0)<br>)|(.*)/ig, 							function( tmp, not_last_line, not_last, last ) {								var aux2 = makeListItem1( not_last_line, not_last, last, open );								return aux2;							} 						);						return aux;					}					else {						return all;					}				} 			)			//transform newlines outside of a span			.replace( /(<li>.*?<\/li>)|((.*?)(?: |\xA0)<br>)|(.+)/ig, 				function( tmp, prev_li, not_last_line, not_last, last ) {					var aux2 = makeListItem2( not_last_line, not_last, last, prev_li );					return aux2;				} 			)			//fix empty lines for Opera			.replace( /<li><\/li>/ig, empty_line )		;		el.innerHTML = '<ol>' + list_items + '</ol>';	} // addLineNumbers	function revealChars( tmp ) {		return $			.map( tmp.split(''), 				function(n, i) { 					return ' ' + n + ' ' + n.charCodeAt( 0 ) + ' ';				} )			.join(' ');	} // revealChars//-----------------------------------------------------------------------------// the coloring starts here	this	.each( function() {		var $this = $( this );		$this.trigger( 'chili.before_coloring' );		askDish( this );		$this.trigger( 'chili.after_coloring' );	} );	return this;//-----------------------------------------------------------------------------};//main$( function() {	if( ChiliBook.automatic ) {		$( ChiliBook.automaticSelector ).chili();	}} );} ) ( jQuery );//YCODASLIDER DEMO BASIC SETTINGChiliBook.recipeFolder = "../../lib/chili/";  ChiliBook
 |