Add no-undefined-references rule

This new rule warns when references to undefined definitions are
found.

Closes GH-35.
This commit is contained in:
Titus Wormer 2016-01-09 22:12:05 +01:00
parent 2c628f20f7
commit 8f6e05562d
6 changed files with 112 additions and 0 deletions

View File

@ -59,6 +59,7 @@ See the readme for a [list of external rules](https://github.com/wooorm/remark-l
* [no-shortcut-reference-link](#no-shortcut-reference-link)
* [no-table-indentation](#no-table-indentation)
* [no-tabs](#no-tabs)
* [no-undefined-references](#no-undefined-references)
* [no-unused-definitions](#no-unused-definitions)
* [ordered-list-marker-style](#ordered-list-marker-style)
* [ordered-list-marker-value](#ordered-list-marker-value)
@ -1055,6 +1056,20 @@ Options: `boolean`, default: `false`.
Warn when hard-tabs instead of spaces
### no-undefined-references
```md
<!-- Valid: -->
[foo][]
[foo]: https://example.com
<!-- Invalid: -->
[bar][]
```
Warn when references to undefined definitions are found.
### no-unused-definitions
```md

View File

@ -70,5 +70,6 @@ module.exports = {
'table-pipes': require('./table-pipes'),
'no-tabs': require('./no-tabs'),
'unordered-list-marker-style': require('./unordered-list-marker-style'),
'no-undefined-references': require('./no-undefined-references.js'),
'no-unused-definitions': require('./no-unused-definitions.js')
};

View File

@ -0,0 +1,82 @@
/**
* @author Titus Wormer
* @copyright 2016 Titus Wormer
* @license MIT
* @module no-unused-definitions
* @fileoverview
* Warn when references to undefined definitions are found.
* @example
* <!-- Valid: -->
* [foo][]
*
* [foo]: https://example.com
*
* <!-- Invalid: -->
* [bar][]
*/
'use strict';
/* eslint-env commonjs */
/*
* Dependencies.
*/
var position = require('mdast-util-position');
var visit = require('unist-util-visit');
/**
* Warn when references to undefined definitions are found.
*
* @param {Node} ast - Root node.
* @param {File} file - Virtual file.
* @param {*} preferred - Ignored.
* @param {Function} done - Callback.
*/
function noUnusedDefinitions(ast, file, preferred, done) {
var map = {};
/**
* Check `node`.
*
* @param {Node} node - Node.
*/
function mark(node) {
if (position.generated(node)) {
return;
}
map[node.identifier.toUpperCase()] = true;
}
/**
* Mark `node`.
*
* @param {Node} node - Node.
*/
function find(node) {
if (position.generated(node)) {
return;
}
if (!map[node.identifier.toUpperCase()]) {
file.warn('Found reference to undefined definition', node);
}
}
visit(ast, 'definition', mark);
visit(ast, 'footnoteDefinition', mark);
visit(ast, 'imageReference', find);
visit(ast, 'linkReference', find);
visit(ast, 'footnoteReference', find);
done();
}
/*
* Expose.
*/
module.exports = noUnusedDefinitions;

View File

@ -0,0 +1 @@
[foo][]

View File

@ -0,0 +1,3 @@
[foo][]
[foo]: https://example.com

View File

@ -1733,6 +1733,16 @@ describe('Rules', function () {
});
});
describeRule('no-undefined-references', function () {
describeSetting(true, function () {
assertFile('no-undefined-references-invalid.md', [
'no-undefined-references-invalid.md:1:1-1:8: Found reference to undefined definition'
]);
assertFile('no-undefined-references-valid.md', []);
});
});
describeRule('no-unused-definitions', function () {
describeSetting(true, function () {
assertFile('no-unused-definitions-invalid.md', [