11 Jul 2009

XBELSort, sort your XBEL bookmarks

I've been using Midori as a web browser for a while and while I really like it, I've found one feature to be missing: sorting bookmarks. Bookmarks in Midori are in XBEL, the XML Bookmark Exchange Language. Knowing this, and wanting to try a little Scala hacking, I made a little application that takes in an XBEL file and sorts the bookmarks alphabetically, and then the folders alphabetically. Usage: scala XBELSort bookmarks.xbel.
import scala.xml._
import scala.xml.dtd._
import scala.util.Sorting
object XBELSort {
	def main(args:Array[String]):Unit = {
		/* Load XML file */
		val in = XML.loadFile(args(0));
		val outfile = args(0).take(args(0).indexOf(".xbel")) + "-sorted.xbel";
		var folders = new NodeBuffer;
		/* Process each folder */
		(in \ "folder").foreach( folder => {
			/* Create a folder element */
			var q = {folder \ "title"}{folder \ "desc"}{getbmarks(folder)};
			/* Append folder element to buffer */
			folders &+ q;
		});
		/* Sort folders by title */
		var sortedFolders = sortNodes(folders);
		/* Wrap in xbel tags */
		var save = {sortedFolders}{getbmarks(in)};
		/* Save sorted xbel to outfile */
		XML.saveFull(outfile,save,"UTF-8",true,new DocType("xbel",PublicID("xbel",null),Seq[Decl]()));
	}
	def getbmarks(a:NodeSeq):Array[Node] = {
		var inside = new NodeBuffer;
		/* Grab bookmarks in this folder */
		(a \ "bookmark").foreach( bmark => {
			var b = {bmark \ "title"}{bmark \ "desc"};
			/* Apply the href= attributes of bmark to b */
			b = b%(bmark.attributes);
			/* Append b to list */
			inside &+ b;
		});
		/* Sort the bookmarks by title */
		return sortNodes(inside);
	}
	/* Sort incoming nodes alphabetically */
	def sortNodes(nb:NodeBuffer):Array[Node] = return Sorting.stableSort[Node](nb,(a:Node,b:Node) => {(a \ "title").text