function transformer( tree, file, clbk ) {
		var nodes;
		var total;
		var dir;
		var idx;

		nodes = [];

		debug( 'Processing virtual file: %s', file.path );
		visit( tree, 'html', visitor );

		total = nodes.length;
		idx = -1;

		debug( 'Found %d equations.', total );
		if ( total === 0 ) {
			return done();
		}
		dir = resolve( file.dirname, opts.dir );
		debug( 'Output directory: %s', dir );

		debug( 'Creating output directory...' );
		return mkdirp( dir, onDir );

		/**
		* Callback invoked upon finding a matching node.
		*
		* @private
		* @param {Node} node - AST node
		*/
		function visitor( node ) {
			if ( EQN_START.test( node.value ) === true ) {
				debug( 'Found an HTML equation.' );
				nodes.push( node );
			}
		}

		/**
		* Callback invoked upon attempting to create a destination directory.
		*
		* @private
		* @param {(Error|null)} error - error object
		* @returns {void}
		*/
		function onDir( error ) {
			if ( error ) {
				debug( 'Error encountered when attempting to create an output directory: %s', error.message );
				return done( error );
			}
			debug( 'Output directory created.' );

			debug( 'Creating SVGs...' );
			next();
		}

		/**
		* Creates the next SVG.
		*
		* @private
		* @returns {void}
		*/
		function next() {
			var raw;
			var err;

			idx += 1;
			raw = RAW.exec( nodes[ idx ].value );
			if ( raw === null ) {
				debug( 'Invalid node: %s', nodes[ idx ].value );
				err = new Error( format( 'invalid node. Equation comments must have valid raw equation text. Node: `%s`.', nodes[ idx ].value ) );
				return done( err );
			}
			raw = raw[ 1 ];
			debug( 'Raw equation: %s', raw );

			tex2svg( raw, onSVG );
		}

		/**
		* Callback invoked upon creating an SVG.
		*
		* @private
		* @param {(Error|null)} error - error object
		* @param {string} svg - SVG string
		* @returns {void}
		*/
		function onSVG( error, svg ) {
			var fopts;
			var fpath;
			var label;

			if ( error ) {
				debug( 'Error encountered when attempting to create an SVG. File: %s. : %s', file.path, error.message );
				return done( error );
			}
			label = LABEL.exec( nodes[ idx ].value );
			if ( label === null ) {
				debug( 'Invalid node: %s', nodes[ idx ].value );
				error = new Error( format( 'invalid node. Equation comments must have valid labels. Node: `%s`.', nodes[ idx ].value ) );
				return done( error );
			}
			label = label[ 1 ];
			debug( 'Equation label: %s', label );

			fpath = join( opts.dir, opts.prefix+label+'.svg' );
			fpath = resolve( file.dirname, fpath );
			debug( 'Absolute filepath: %s', fpath );

			fopts = {
				'encoding': 'utf8'
			};

			debug( 'Writing SVG to file...' );
			writeFile( fpath, svg, fopts, onWrite );
		}

		/**
		* Callback invoked upon writing an SVG to file.
		*
		* @param {(Error|null)} error - error object
		* @returns {void}
		*/
		function onWrite( error ) {
			if ( error ) {
				debug( 'Error encountered when attempting to write an SVG to file: %s', error.message );
				return done( error );
			}
			debug( 'SVG successfully written to file.' );
			done();
		}

		/**
		* Callback invoked once finished processing an AST.
		*
		* @private
		* @param {(Error|null)} error - error object
		* @returns {void}
		*/
		function done( error ) {
			if ( error ) {
				return clbk( error );
			}
			if ( idx === total-1 ) {
				debug( 'Finished processing virtual file.' );
				return clbk();
			}
			next();
		}
	}
Transforms a Markdown abstract syntax tree (AST).

@private
@param {Node} tree - root node of the AST
@param {File} file - virtual file
@param {Callback} clbk - callback to invoke upon completion
@returns {void}