function main( context ) {
	var comments;
	var options;
	var visited;
	var source;
	var opts;

	opts = copy( DEFAULTS );
	options = context.options[ 0 ];
	if ( hasOwnProp( options, 'whitelist' ) ) {
		opts.whitelist = options.whitelist.slice();
	}
	source = context.getSourceCode();
	visited = {};

	/**
	* Reports the error message.
	*
	* @private
	* @param {Object} comment - comment node
	*/
	function report( comment ) {
		context.report({
			'node': null,
			'message': 'Comments should begin with an uppercase character',
			'loc': comment.loc,
			'fix': fix
		});

		/**
		* Fixes the lint error by capitalizing the first letter of a comment.
		*
		* @private
		* @param {Function} fixer - ESLint fixer
		* @returns {(Object|null)} fix or null
		*/
		function fix( fixer ) {
			var replacement;
			var idx;
			var str;
			var ch;

			str = source.getText( comment );
			idx = str.search( /[a-zA-Z]/ );
			ch = str.charAt( idx ).toUpperCase();
			replacement = str.slice( 0, idx ) + ch + str.slice( idx+1 );
			return fixer.replaceText( comment, replacement );
		}
	}

	/**
	* Checks whether first word of the comment is capitalized or contained in the exceptions whitelist.
	*
	* @private
	* @param {ASTNode} comment - comment node
	* @param {Object} scope - scope of current node
	*/
	function processComment( comment, scope ) {
		var found;
		var stext;
		var char;
		var text;
		var word;
		var i;

		text = ltrim( comment.value );
		if ( RE_LETTERS.test( text ) ) { // Note: JSDoc comments are not checked...
			if (
				!isInlineComment( comment ) &&
				!isCapitalized( text )
			) {
				found = false;
				stext = '';
				for ( i = 0; i < text.length; i++ ) {
					char = text[ i ];
					if ( char === '\n' || char === ' ' ) {
						break;
					}
					stext += char;
				}
				if ( scope.set.has( stext ) ) {
					found = true;
				} else if ( RE_SPECIAL_CHARS.test( stext ) ) {
					// Do not flag first word if it contains special characters (e.g., `x-value`):
					found = true;
				} else {
					// Check if the first word is contained in the whitelist (e.g., `ndarray`):
					for ( i = 0; i < opts.whitelist.length; i++ ) {
						word = opts.whitelist[ i ];
						if ( stext === word ) {
							found = true;
							break;
						}
					}
				}
				// If word is not in whitelist, has no special characters, and is not found in current scope, raise an error:
				if ( !found ) {
					report( comment );
				}
			}
		}
	}

	/**
	* Checks whether a comment is an inline block comment or a trailing line comment.
	*
	* ## Notes
	*
	* -   A comment is regarded as an inline block comment if it is preceded by a token on the same line and followed by a token on the same line.
	* -   A comment is a trailing line comment if it starts with `//` and has a preceding token on the same line
	*
	* @private
	* @param {ASTNode} comment - comment node
	* @returns {boolean} boolean indicating whether a comment is an inline block comment or trailing line comment
	*/
	function isInlineComment( comment ) {
		var hasPreceding;
		var previous;
		var next;

		previous = source.getTokenBefore( comment, OPTS );
		if ( previous ) {
			hasPreceding = comment.loc.start.line === previous.loc.end.line;
		} else {
			hasPreceding = false;
		}
		next = source.getTokenAfter( comment, OPTS );
		if ( comment.type === 'Line' ) {
			return hasPreceding;
		}
		return (
			next &&
			hasPreceding &&
			comment.loc.end.line === next.loc.start.line
		);
	}

	/**
	* Checks whether comments start with an uppercase letter.
	*
	* @private
	* @param {ASTNode} node - program to examine
	*/
	function validate( node ) {
		var comment;
		var scope;
		var i;

		comments = source.getCommentsInside( node );
		scope = context.getScope( node );
		for ( i = 0; i < comments.length; i++ ) {
			comment = comments[ i ];
			if ( comment.type !== 'Shebang' && !visited[ comment.range ] ) {
				processComment( comment, scope );
			}
			visited[ comment.range ] = true;
		}
	}

	return {
		'Program:exit': validate,
		'FunctionDeclaration': validate,
		'FunctionExpression': validate
	};
}
Rule for validating that comments start with an uppercase letter.

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