Jul 08 2007

Introducing HotChili

Tag: Chili, HotChiliAndrea Ercolino @ 13:07:35

The rationale behind Chili is that I need highlighted code to understand a program listing. I developed Chili to make it really easy for every blogger to add highlighting to their own code snippets.

The rationale behind HotChili is that many sites still don’t use any highlighting at all, and that bothers me. I developed HotChili to make it really easy for every internet user to add highlighting to someone else’s code snippets.

HotChili is a Greasemonkey user script (plugin), so it runs on any FireFox browser with that extension installed. HotChili is very easy to install and easier to use. Just click on a dull snippet and spice it up by selecting a language off the popup menu. If you change your mind, click again and undo it. That’s all!!

Install HotChili

After installing HotChili, you can browse the web as usual. If you want to test it, here is a short list of good programming pages that lack any highlighting: 1, 2, 3, 4, 5

As you see, HotChili is very simple to use and adds quite a readability factor to code. My advise is to turn it off during normal browsing, and turn it on when you really need it.


May 27 2007

Chili 1.8b Released Today

Tag: ChiliAndrea Ercolino @ 20:56:43

UPDATE: Chili 1.8c has been released

Changes
  • Fixed a bug that showed up when the content of an element to highlight was not a single chunk: in that case the content was erased. Now such an element won’t be highlighted by Chili.
    Content without markup is one chunk, which makes it possible to apply Chili’s markup.
Files
  • download all in a zip
  • read the manual
  • Examples
    • bundled languages
      this page shows how Chili highlights the bundled languages: JavaScript, PHP, MySQL, XHTML, Java, C++, C#, Delphi, and LotusScript (BTW, using the dynamic and automatic setup)
    • static, automatic, adhoc: this page shows how to setup Chili for
      • downloading recipes and stylesheets all at once, using HTML
      • highlighting code sections automatically
      • highlighting code sections ad-hoc
    • dynamic, automatic, adhoc: this page shows how to setup Chili for
      • downloading recipes and stylesheets as needed, using AJAX
      • highlighting code sections automatically
      • highlighting code sections ad-hoc
    • dynamic, automatic, adhoc, metaobjects: this page shows how to setup Chili for
      • downloading recipes and stylesheets as needed, using AJAX
      • highlighting code sections automatically
      • highlighting code sections ad-hoc
      • highlighting code sections using special recipes and stylesheets, by means of metaobjects
    • all the other combinations: this page shows all the other possible combinations

May 25 2007

Chili 1.8a Released Today

Tag: ChiliAndrea Ercolino @ 22:04:16

UPDATE: Chili 1.8b has been released

Changes
  • Fixed a bug that showed up when the metadataSelector option was an empty string. Now that value is used for telling Chili not to execute the metaobjects plugin (which Chili executes by default)
  • Some minor cleanup
  • Renamed the bundled jQuery library to reflect the correct version number (1.1.2)
Files
  • download all in a zip
  • read the manual
  • Examples
    • bundled languages
      this page shows how Chili highlights the bundled languages: JavaScript, PHP, MySQL, XHTML, Java, C++, C#, Delphi, and LotusScript (BTW, using the dynamic and automatic setup)
    • static, automatic, adhoc: this page shows how to setup Chili for
      • downloading recipes and stylesheets all at once, using HTML
      • highlighting code sections automatically
      • highlighting code sections ad-hoc
    • dynamic, automatic, adhoc: this page shows how to setup Chili for
      • downloading recipes and stylesheets as needed, using AJAX
      • highlighting code sections automatically
      • highlighting code sections ad-hoc
    • dynamic, automatic, adhoc, metaobjects: this page shows how to setup Chili for
      • downloading recipes and stylesheets as needed, using AJAX
      • highlighting code sections automatically
      • highlighting code sections ad-hoc
      • highlighting code sections using special recipes and stylesheets, by means of metaobjects
    • all the other combinations: this page shows all the other possible combinations

May 17 2007

Chili 1.8 Released Today

Tag: ChiliAndrea Ercolino @ 20:30:54

UPDATE: Chili 1.8a has been released

Changes
  • Added chainability
    • $( selector ).chili( options )… should work fine with almost all ChiliBook options
  • Improved speed
  • Improved examples
  • Added an automatic option, by default set to true
    • use true for executing Chili on page load
    • use false for not executing Chili on page load
  • Integrated the metaobjects plugin
  • Exposed the metaobjects selector by means of the metadataSelector option, by default set to object.chili
    • you can now use a different selector, but the param’s name still needs to be chili
  • Improved the elementPath / elementClass feature by means of the new options automaticSelector / codeLanguage
    • automaticSelector is a better name for elementPath
    • codeLanguage is a function that gets the element to highlight as an argument and returns the language to highlight it with
    • elementPath and elementClass are still supported
  • Fixed a bug that made Chili highlight more code sections than requested in dynamic setups, under special circumstances
Files
  • download all in a zip
  • read the manual
  • Examples
    • bundled languages
      this page shows how Chili highlights the bundled languages: JavaScript, PHP, MySQL, XHTML, Java, C++, C#, Delphi, and LotusScript (BTW, using the dynamic and automatic setup)
    • static, automatic, adhoc: this page shows how to setup Chili for
      • downloading recipes and stylesheets all at once, using HTML
      • highlighting code sections automatically
      • highlighting code sections ad-hoc
    • dynamic, automatic, adhoc: this page shows how to setup Chili for
      • downloading recipes and stylesheets as needed, using AJAX
      • highlighting code sections automatically
      • highlighting code sections ad-hoc
    • dynamic, automatic, adhoc, metaobjects: this page shows how to setup Chili for
      • downloading recipes and stylesheets as needed, using AJAX
      • highlighting code sections automatically
      • highlighting code sections ad-hoc
      • highlighting code sections using special recipes and stylesheets, by means of metaobjects
    • all the other combinations: this page shows all the other possible combinations

Apr 27 2007

PunchCard 1.3 Released Today

Tag: PunchCardAndrea Ercolino @ 20:20:44
Changes
Files

(the greeny thing below this line is a punchcard)


Apr 21 2007

Optimize using dictionaries

Tag: ToolkitAndrea Ercolino @ 16:52:00

There is a jQuery plugin for simplifying access to a select box. It’s very useful and I tried to use it in a prioject where I had to show hundreds of options at once. It worked pretty well with a few options, but as soon as those many options started to come in, performance fell down.

Let’s have a look at the implementation of the addOption function.

$.fn.addOption = function()
{
	var a = arguments;
	if(a.length == 0) return this;
	// select option when added? default is true
	var sO = true;
	// multiple items
	var m = false;
	if(typeof a[0] == "object")
	{
		m = true;
		var items = a[0];
	}
	if(a.length >= 2)
	{
		if(typeof a[1] == "boolean") sO = a[1];
		else if(typeof a[2] == "boolean") sO = a[2];
		if(!m)
		{
			var v = a[0];
			var t = a[1];
		}
	}
	this.each(
		function()
		{
			if(this.nodeName.toLowerCase() != "select") return;
			if(m)
			{
				for(var i in items)
				{
					$(this).addOption(i, items[i], sO);
				}
			}
			else
			{
				var option = document.createElement("option");
				option.value = v;
				option.text = t;
				var i;
				var r = false;
				// get options
				var o = this.options;
				// get number of options
				var oL = o.length;
				// loop through existing options
				for(i = 0; i < oL; i++)
				{
					// replace existing option
					if(o[i].value == option.value)
					{
						r = true;
						break;
					}
				}
				if(i < oL && !r) i = oL;
				this.options[i] = option;
				if(sO)
				{
					o[i].selected = true;
				}
			}
		}
	)
	return this;
}

Off Topic: The code above is a bit complex at first sight. The reason it seems complex is due to unneeded recursion, so common among jQuery developers. In fact the jQuery library itself makes use of unneeded recursion whenever possible…

Look at the snippet below the comment // loop through existing options. What’s going on here? A select box is treated like a database table where an option is a record and its value is the primary key. When an option is added to a select box, the everlasting dilemma arises: Is it an INSERT or an UPDATE?

The solution implemented here is to loop through existing options and break if a match is found between the new option value and the old ones. Sadly enough, this is the optimal (linear length) solution if you are adding just one option, but it’s the worst (quadratic length) one when you are adding many options at once.

Here is a replacement using a dictionary for storing and retrieving existing options. It’s an inner refactoring with no change on the interface, so it’s pretty simple to copy and use it in your own projects.

var options_dictionary;
var options_count;
function init_options( el ) {
	var o = el.options;
	options_count = o.length;
	options_dictionary = {};
	for(i = 0; i < options_count; i++) {
		options_dictionary[ o[i].value ] = i;
	}
}
function addOneOption( el, value, text, selected ) {
	var option = document.createElement("option");
	option.value = value;
	option.text = text;
	if( selected ) option.selected = true;

	var o = el.options;
	var i = options_dictionary[ value ];
	if( typeof i == 'undefined' ) {
		i = options_count;
		options_dictionary[ value ] = i;
		options_count++;
	}
	o[i] = option;
}

$.fn.addOption = function()
{
	var a = arguments;
	if(a.length == 0) return this;
	// select option when added? default is true
	var sO = true;
	// multiple items
	var m = false;
	if(typeof a[0] == "object")
	{
		m = true;
		var items = a[0];
	}
	if(a.length >= 2)
	{
		if(typeof a[1] == "boolean") sO = a[1];
		else if(typeof a[2] == "boolean") sO = a[2];
		if(!m)
		{
			var v = a[0];
			var t = a[1];
		}
	}
	this.each(
		function()
		{
			if(this.nodeName.toLowerCase() != "select") return;
			init_options( this );
			if(m)
			{
				for(var i in items)
				{
					addOneOption( this, i, items[i], sO );
				}
			}
			else
			{
				addOneOption( this, v, t, sO );
			}
		}
	)
	return this;
}

The performance improvement is huge. Here are some figures I got on my PC by means of the Firebug Profiler.

  • all INSERTs: adding 1000 options to an empty select box needed 15234.375 milliseconds using the original code and 234.375 milliseconds using the replacement code, thus accounting for a 65 times improvement
  • all UPDATEs: replacing all the 1000 options of a select box needed 16578.125 milliseconds using the original code and 796.875 milliseconds using the replacement code, thus accounting for a 20 times improvement

If you want to test it by yourself here is the simple page I used:

<head>
<title> test dictionary </title>

<script type="text/javascript" src="jquery-latest.pack.js"></script>
<script type="text/javascript" src="jquery-select-test.js"></script>

<script type="text/javascript">
$( function() {
	manyOptions = {}; //global
	for( var i = 0, top = 1000; i < top; i++ ) {
		manyOptions[ ''+(9999-i) ] = 'this is the new option '+i;
	}

	var preload = {};
	for( var i = 0, top = 1000; i < top; i++ ) {
		preload[ ''+(9999-i) ] = 'this is the old option '+i;
	}
	$( '#mySelectPreloaded' ).addOption( preload, false );

	$( '#mySelect_Load' ).click( function() {
		$( '#mySelect' ).addOption( manyOptions, false );
	} );
	$( '#mySelectPreloaded_Load' ).click( function() {
		$( '#mySelectPreloaded' ).addOption( manyOptions, false );
	} );
} );
</script>

</head>
<body>

<p><select id='mySelect'></select> <a href="#" id="mySelect_Load">Load (Empty)</a></p>
<p><select id='mySelectPreloaded'></select> <a href="#" id="mySelectPreloaded_Load">Load (Preloaded)</a></p>

</body>
</html>


Mar 02 2007

How to add semantics to WordPress posts

Tag: EnzymesAndrea Ercolino @ 10:49:35

Browsing the WordPress’ ideas repository I’ve found one that could make WordPress fill the gap between a blog tool and a knowledge base: Structured Blogging.

The fact that it got 60 votes but only 50% stars means two things:

  1. voting people are lazy thinkers
  2. it’s a difficult task at many levels

Nonetheless it’s a good idea because this is and will be for many years to come the blogging era, where millions of authors post content to the Internet. There is no good reason for that content to be unstructured except lazyness and complexity.

Nothing can be done about lazyness but complexity can be substantially reduced. The solution needs:

  • a mechanism for adding XML tags from some dictionary
  • a template system for showing XML content appropiately

On the path to something readily usable (I hope Matt will provide it in WordPress 3.0), a mechanism could be a jQuery plugin for the visual editor, and a template system could be based on Enzymes.

Autocompletion

I think that tinyMCE can be extended by plugins, but I don’t know how to. jQuery itself has an autocompletion plugin that could be used this way. When an author presses a < key, the autocompletion gets triggered and the popup … pops up :-)

If you have ever used IME (for Japanese for example), you should know what I mean. Options are organized in a hierarchy and you get the most relevant at the top, depending on the few characters already typed. XML dictionaries could be ajaxed and locally cached; they could be plugins that you install into your blog, or be web services too; they could be international standards compliant or be completely custom.

The most-relevant-first feature of the autocompletion popup would be a big help for authors. If I already opened a Tag, then the most relevant options after pressing < could be:

  1. the closing tag for that Tag
  2. any tag that could be inside that Tag (properly sorted if needed)
  3. any root of the cached dictionaries (if possible in Tag)
  4. an option for accessing additional dictionaries (if possible in Tag)

Templates

A PHP template for properly rendering XML content is very easy to write, and Enzymes could be used in the clockwork. In fact an Enzymes feature is the possibility of easily transcluding all the content of a post or a page by means of the special char *

The XML to HTML template can be transformed in an Enzymes template with a couple of PHP instructions, thus allowing you to almost copy and paste already available templates. Then you could apply a solution like this:

  1. write a private post or page with the XML content, using the autocompletion feature described above (say this post is #123)
  2. write a public post or page with the Enzymes statement {[123.* /template.php]} in its content

The post in 1. needs to be private because you don’t want it to appear on the blog as is, and 2. makes the transformation happen. As an added benefit, you can display that semantic content inside of a greater context, and you can transclude it wherever you want in your WordPress blog (as many times as you like).


« Previous PageNext Page »