remark-lint/packages/remark-lint-fenced-code-marker/index.js
Titus Wormer 282d27606d Refactor readme.mds
This commit rewrites most of the documentation per rule and preset,
`remark-lint` itself, and `unified-lint-rule`.

* Better and more readable automatic examples
* Check and update all rule descriptions
* Use middot (·) and line-feed (␊) for relevant examples
* Unify descriptions of `'consistent`'
* Add some more docs where needed

Closes GH-158.
2017-08-17 13:52:59 +02:00

108 lines
2.3 KiB
JavaScript

/**
* @author Titus Wormer
* @copyright 2015 Titus Wormer
* @license MIT
* @module fenced-code-marker
* @fileoverview
* Warn for violating fenced code markers.
*
* Options: `` '`' ``, `'~'`, or `'consistent'`, default: `'consistent'`.
*
* `'consistent'` detects the first used fenced code marker style and warns
* when subsequent fenced code-blocks use different styles.
*
* @example {"name": "valid.md"}
*
* Indented code blocks are not affected by this rule:
*
* bravo();
*
* @example {"name": "valid.md", "setting": "`"}
*
* ```alpha
* bravo();
* ```
*
* ```
* charlie();
* ```
*
* @example {"name": "valid.md", "setting": "~"}
*
* ~~~alpha
* bravo();
* ~~~
*
* ~~~
* charlie();
* ~~~
*
* @example {"name": "invalid.md", "label": "input"}
*
* ```alpha
* bravo();
* ```
*
* ~~~
* charlie();
* ~~~
*
* @example {"name": "invalid.md", "label": "output"}
*
* 5:1-7:4: Fenced code should use ` as a marker
*
* @example {"name": "invalid.md", "setting": "!", "label": "output", "config": {"positionless": true}}
*
* 1:1: Invalid fenced code marker `!`: use either `'consistent'`, `` '`' ``, or `'~'`
*/
'use strict';
var rule = require('unified-lint-rule');
var visit = require('unist-util-visit');
var position = require('unist-util-position');
var generated = require('unist-util-generated');
module.exports = rule('remark-lint:fenced-code-marker', fencedCodeMarker);
var MARKERS = {
'`': true,
'~': true,
null: true
};
function fencedCodeMarker(ast, file, preferred) {
var contents = file.toString();
preferred = typeof preferred !== 'string' || preferred === 'consistent' ? null : preferred;
if (MARKERS[preferred] !== true) {
file.fail('Invalid fenced code marker `' + preferred + '`: use either `\'consistent\'`, `` \'`\' ``, or `\'~\'`');
}
visit(ast, 'code', visitor);
function visitor(node) {
var marker = contents.substr(position.start(node).offset, 4);
if (generated(node)) {
return;
}
marker = marker.trimLeft().charAt(0);
/* Ignore unfenced code blocks. */
if (MARKERS[marker] !== true) {
return;
}
if (preferred) {
if (marker !== preferred) {
file.message('Fenced code should use ' + preferred + ' as a marker', node);
}
} else {
preferred = marker;
}
}
}