Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,6 @@ Icon
Network Trash Folder
Temporary Items
.apdisk

# IDE files
.idea/
634 changes: 321 additions & 313 deletions docs/example-triggers.html

Large diffs are not rendered by default.

392 changes: 392 additions & 0 deletions docs/js/chili/chili-1.8b.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,392 @@
/*
===============================================================================
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: '<span class="$0">$$</span>'

, replaceSpace: "&#160;" // use an empty string for not replacing
, replaceTab: "&#160;&#160;&#160;&#160;" // use an empty string for not replacing
, replaceNewLine: "&#160;<br/>" // 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, "&amp;" ).replace( /</g, "&lt;" );
} // function escapeHTML( str )

function replaceSpaces( str ) {
return str.replace( / +/g, function( spaces ) {
return spaces.replace( / /g, replaceSpace );
} );
} // function replaceSpaces( str )

function filter( str ) {
str = escapeHTML( str );
if( replaceSpace ) {
str = replaceSpaces( str );
}
return str;
} // function filter( str )

function chef( matched ) {
var i = 0; // iterate steps
var j = 1; // iterate chef's arguments
var step;
while( step = steps[ i++ ] ) {
var aux = arguments; // this unmasks chef's arguments inside the next function
if( aux[ j ] ) {
var pattern = /(\\\$)|(?:\$\$)|(?:\$(\d+))/g;
var replacement = step.replacement
.replace( pattern, function( m, escaped, K ) {
var bit = '';
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 ) ] );
}
} );

var offset = arguments[ arguments.length - 2 ];
var input = arguments[ arguments.length - 1 ];
var unmatched = input.substring( lastIndex, offset );
lastIndex = offset + matched.length; // lastIndex for the next call to chef

perfect += filter( unmatched ) + replacement; // use perfect for all the replacing
return replacement;
}
else {
j+= step.length;
}
}
} // function chef( matched )

var replaceSpace = book.replaceSpace;
var steps = new Array;
for( var stepName in recipe.steps ) {
prepareStep( stepName, recipe.steps[ stepName ] );
}

var perfect = ""; //replace doesn't provide a handle to the ongoing partially replaced string
var lastIndex = 0; //regexp.lastIndex is available after a string.match, but not in a string.replace
ingredients.replace( knowHow(), chef );
var lastUnmatched = ingredients.substring( lastIndex, ingredients.length );
perfect += filter( lastUnmatched );

return perfect;

} // function cook( ingredients, recipe )

function checkCSS( stylesheetPath ) {
if( ! book.queue[ stylesheetPath ] ) {
var e = document.createElement( "link" );
e.rel = "stylesheet";
e.type = "text/css";
e.href = stylesheetPath;
document.getElementsByTagName( "head" )[0].appendChild( e );

book.queue[ stylesheetPath ] = true;
}
} // function checkCSS( recipeName )

function makeDish( el, recipePath ) {
var recipe = book.recipes[ recipePath ];
if( ! recipe ) {
return;
}
var chunks = el && el.childNodes && el.childNodes.length;
if( chunks && chunks > 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( /\<br[^>]*?\>/ig, newline_flag );
var el = document.createElement( '<pre>' );
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 );
Loading