O'Reilly Hacks
oreilly.comO'Reilly NetworkSafari BookshelfConferences Sign In/My Account | View Cart   
Book List Learning Lab PDFs O'Reilly Gear Newsletters Press Room Jobs  


 
Buy the book!
Greasemonkey Hacks
By Mark Pilgrim
November 2005
More Info

HACK
#44
Filter Code Examples on MSDN
Display only the MSDN code samples and APIs for the languages you care about
The Code
[Discuss (0) | Link to this hack]

The Code

This user script runs on http://msdn.microsoft.com. The biggest question for overlaying the feature on top of MSDN is, "How structured is the content? How easy is it to identify sections showing a specific language?" Even though the markup isn't as clean as I had hoped, it is barely regular enough that I was able to filter code examples by language.

When I looked at the source of some MSDN reference pages, the markup for code snippets read something like this:

<grouping>
		<span class="lang">C#</span> …many nodes…
		<span class="lang">JScript</span> …many nodes…
	</grouping>

The grouping tag varies from page to page. Sometimes it's a <div>, but I also found <pre> elements on some pages. Although this markup is good enough for styling the page, it doesn't lend itself to easy filtering. Each language section doesn't have its own container, which makes it difficult to identify all the DOM nodes for the code sample.

The script starts by finding all the span elements that have a class="lang" attribute. It then scans the content of each <span> to identify known language names. The ShowCS, ShowVB, ShowCPP, and ShowJScript variables let you customize which languages to show or hide. If the code sample is an identifiable language and the corresponding Show variable is true, we keep it; otherwise, we remove it.

Finally, the CleanSpan function handles filtering out a language section, for a given starting <span>, by also providing the next known language <span> (if any). It removes all the sibling nodes that follow the starting <span>, until it reaches the <span> for the following language section or until there is no next sibling node (i.e., until we reach the end of the grouping). This is the best we can do, given the paucity of structured markup.

Save the following user script as MSDNLanguageFilter.user.js:

	// ==UserScript==
	// @name		MSDN Language Filter
	// @namespace	http://blog.monstuff.com/archives/cat_greasemonkey.html
	// @description Allows you to filter the samples on MSDN for certain
languages
	// @include		http://msdn.microsoft.com/*
	// ==/UserScript==

	// based on code by Julien Couvreur
	// and included here with his gracious permission

	var ShowCPP = false;
	var ShowVB = false;
	var ShowJScript = false;
	var ShowCS = true;

	var MSDNLanguageFilter = {
		FilterLanguages: function()
		{	
			var xpath = "//span[@class = 'lang']";
			var res = document.evaluate(xpath, document, null,
				XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);

			for (var i = 0; i < res.snapshotLength; i++)
			{
				var spanHTML = res.snapshotItem(i).innerHTML;

				var isVB = (spanHTML.match(/Visual.*Basic/i) != null);
				var isCS = (spanHTML.match(/C#/i) != null);
				var isCPP = (spanHTML.match(/C\+\+/i) != null);
				var isJScript = (spanHTML.match(/JScript/i) != null);

				if (!isVB && !isCS && !isCPP && !isJScript)
				{
				return;
				}	

				var keepLang =
				(isCPP && ShowCPP) ||
				(isCS && ShowCS) ||
				(isVB && ShowVB) ||
				(isJScript && ShowJScript) ||
				(!isCPP && !isCS && !isVB && !isJScript);
			  
				if (!keepLang)
				{
				this.CleanSpan(res.snapshotItem(i), res.snapshotItem(i+1));
				}
			}
		},

		CleanSpan: function(startSpan, endSpan)
		{
			var currentNode = startSpan;
			while (currentNode != null &&
				(endSpan == null || currentNode != endSpan))
			{
				var nextNode = currentNode.nextSibling;
				currentNode.parentNode.removeChild(currentNode);
				currentNode = nextNode;
			}

		}
	 }

	 MSDNLanguageFilter.FilterLanguages();


O'Reilly Home | Privacy Policy

© 2007 O'Reilly Media, Inc.
Website: | Customer Service: | Book issues:

All trademarks and registered trademarks appearing on oreilly.com are the property of their respective owners.