function main( context ) {
	var options;
	var source;
	var lint;
	var opts;

	options = context.options[ 0 ];
	opts = {};
	if ( hasOwnProp( options, 'config' ) ) {
		opts.config = options.config;
	} else {
		opts.config = {};
	}
	lint = remark().use( opts.config ).processSync;
	source = context.getSourceCode();

	return {
		'FunctionExpression:exit': validate,
		'FunctionDeclaration:exit': validate,
		'VariableDeclaration:exit': validate,
		'ExpressionStatement:exit': validate
	};

	/**
	* Lints JSDoc descriptions.
	*
	* @private
	* @param {ASTNode} node - AST node
	*/
	function validate( node ) {
		var jsdoc;
		var vfile;
		var ast;

		jsdoc = findJSDoc( source, node );
		if ( isObject( jsdoc ) ) {
			ast = parseJSDoc( jsdoc.value, DOPTS );
			if ( ast.description ) {
				vfile = lint( ast.description );
				if ( vfile.messages.length ) {
					reportErrors( vfile.messages, jsdoc.loc );
				}
			}
		}
	}

	/**
	* Reports Markdown lint errors.
	*
	* @private
	* @param {ObjectArray} errors - Markdown lint errors
	* @param {Object} loc - JSDoc location information
	*/
	function reportErrors( errors, loc ) {
		var err;
		var msg;
		var i;
		for ( i = 0; i < errors.length; i++ ) {
			err = errors[ i ];
			msg = err.name;
			msg += '  ';
			if ( err.fatal ) {
				msg += 'error';
				msg += '    ';
			} else {
				msg += 'warning';
				msg += '  ';
			}
			msg += err.message;
			msg += '  ';
			msg += err.ruleId;
			msg += '  ';
			msg += err.source;
			report( msg, loc );
		}
	}

	/**
	* Reports an error message.
	*
	* @private
	* @param {string} msg - error message
	* @param {Object} loc - AST node location
	*/
	function report( msg, loc ) {
		context.report({
			'node': null,
			'message': msg,
			'loc': loc
		});
	}
}
Rule for linting JSDoc descriptions using remark.

@param {Object} context - ESLint context
@returns {Object} validators