Skip to content

Collapse/expand syntax highlighted block

I quote often surf Intel’s website in search for CPU articles, and I found that Intel has quite nicely formatted code examples on their pages. Being as I am, I took a peek at their html I found that source code formatting probably has to do with SyntaxHighlighter.css. Magic of Google got me soon to syntax highlighter page. I downloaded the latest version and got this:
syntax1
That is cool, but I don’t really like that little button popup in the right corner. It is a bit too fancy for me with buttons popping up whenever I move cursor over the box. There is also no feature to collapse/expand the source. What I really wanted was this little row as seen here:
syntax2
So I tested older version (1.5.1) which seemed to be more of what I wanted, and also lighter in size. However as seen from the example on SyntaxHighlighter webpage, there is no really expand/collapse option:
syntax3

According to docs one can pass collapse in <pre name=”code” class=”brushname:collapse”>. With that option one gets an extra button with text +expand on, but once the box is expanded, there is no way to collapse it again. Further search directed me to Dan’s blog. He had similar thoughts as me, and coded a simple hack, which almost works as I would like it. Problem with his hack is the default folding. One must specify code box as collapsed from the very beginning, otherwise it won’t work at all – there will be no collapse/expand option, just like in original. So below is hack over Dan’s hack to add +collapse option to the toolbar by default, and +expand if you specify brushname:collapse option.

I had to change those places that Dan hacked as below:


	ExpandSource: {
		label: '+ expand source',
		func: function(sender, highlighter)
		{
            // dan's hack for expand collapse toggle.
            var a = document.createElement("a");
            a.setAttribute('href', '#');
            a.onclick = function() {
                dp.sh.Toolbar.Command('CollapseSource',this);
                return false;
            }
            a.appendChild(document.createTextNode("- collapse source"));
            // end hack section

            sender.parentNode.insertBefore(a, sender);
	    sender.parentNode.removeChild(sender);
            
            highlighter.div.className = highlighter.div.className.replace('collapsed', '');
		}
	},

	// dan's hack for expand collapse toggle.
	CollapseSource: {
		label: '- collapse source',
		func: function(sender, highlighter)
		{
		    var a = document.createElement("a");
		    a.setAttribute('href', '#');
		    a.onclick = function() {
			dp.sh.Toolbar.Command('ExpandSource',this);
			return false;
		    }
		    a.appendChild(document.createTextNode("+ expand source"));
		    sender.parentNode.insertBefore(a, sender);
		    sender.parentNode.removeChild(sender);
		    highlighter.div.className = highlighter.div.className + ' collapsed';
		}
	},
	// end dan's hack

As seen, more or less everything Dan done was right, but the check() function had wrong logic and is unnecessary.

        // in CollapseView command
        check: function(highlighter) { return highlighter.collapse; }, 

       // in ExpandView command
        check: function(highlighter) { return false; }, 

After the check is removed, I changed function where commands are added to the toolbar as follows:

// creates a 
with all toolbar links dp.sh.Toolbar.Create = function(highlighter) { var div = document.createElement('DIV'); div.className = 'tools'; for(var name in dp.sh.Toolbar.Commands) { var cmd = dp.sh.Toolbar.Commands[name]; // hacked part if(name == 'ExpandSource' && highlighter.collapse == false) continue; else if(name == 'CollapseSource' && highlighter.collapse == true) continue; else div.innerHTML += '' + cmd.label + ''; } return div; }

The result as seen from this post is collapsable/expandable toolbar button, just as seen above on intel’s page. There may be better way to do this, as Dan says, but this works so far. Thanks to Dan for making original hack, since I am not javascript programmer, I really have no idea about DOM and what elements are avialable and through which functions, so I would probably never manage to fix this on my own.

While googeling around for those solutions, I found that syntax highlighter is quite popular library. It is used by many sites, both personal and professional, mighty Intel being just one. There also seems to be many hacked versions of original source, with people adding all bunch of diverse funcionality. Probably the most popular one is SyntaxHighlighter Evolved. Be sure to check authors page, he has written some other good wordpress plugins.

There are also other syntax highlighting engines beside SyntaxHighlight, another very popular is GeSHI, also avialable as a WordPress plugin. Of course there are others as well, varying in features and resources used, here is a little survey of what is avialable.

3 Comments

  1. danb wrote:

    thanks for the link arthur.

    I think that worked back when I made the patch, as the code samples on my site behave the correct way (i think)… anyway, good job! this is a great bit of code that I’ve found very useful. I’m going to be installing it in my new blog some time this week.

    dan

    Tuesday, July 7, 2009 at 4:54 pm | Permalink
  2. Harish wrote:

    Thanks for the nice hack. I got it working using version 1.5.1

    However I couldn’t apply the same hack for version 2.1.364 version of SyntaxHighlighter. It has got completely different code.

    Can you please suggest if there any hacks for getting the collapse / expand option in version 2.1.364

    Thursday, December 17, 2009 at 2:05 pm | Permalink
  3. admin wrote:

    I am sorry but I don’t know. I have looked at the source but as you say the code is much more different.

    Since I found the 2.x versions to be bigger, slower, and doesn’t behave as I would like, I didn’t event try.
    Old version has all I need, and is smaller and faster than version 2.x so I am fine with old one so far.

    Friday, December 18, 2009 at 4:10 pm | Permalink

Post a Comment

Your email is never published nor shared. Required fields are marked *
*
*