Skip to content

Commit

Permalink
Add load-plugin to load external rules
Browse files Browse the repository at this point in the history
  • Loading branch information
wooorm committed Aug 1, 2016
1 parent 5a70271 commit 31f82b2
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 153 deletions.
127 changes: 64 additions & 63 deletions doc/rules.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,75 +6,74 @@ fix their warnings.

See the readme for a [list of external rules](https://github.com/wooorm/remark-lint#list-of-external-rules).

## Table of Contents

* [Rules](#rules)
* [external](#external)
* [reset](#reset)
* [blockquote-indentation](#blockquote-indentation)
* [checkbox-character-style](#checkbox-character-style)
* [checkbox-content-indent](#checkbox-content-indent)
* [code-block-style](#code-block-style)
* [definition-case](#definition-case)
* [definition-spacing](#definition-spacing)
* [emphasis-marker](#emphasis-marker)
* [fenced-code-flag](#fenced-code-flag)
* [fenced-code-marker](#fenced-code-marker)
* [file-extension](#file-extension)
* [final-definition](#final-definition)
* [final-newline](#final-newline)
* [first-heading-level](#first-heading-level)
* [hard-break-spaces](#hard-break-spaces)
* [heading-increment](#heading-increment)
* [heading-style](#heading-style)
* [link-title-style](#link-title-style)
* [list-item-bullet-indent](#list-item-bullet-indent)
* [list-item-content-indent](#list-item-content-indent)
* [list-item-indent](#list-item-indent)
* [list-item-spacing](#list-item-spacing)
* [maximum-heading-length](#maximum-heading-length)
* [maximum-line-length](#maximum-line-length)
* [no-auto-link-without-protocol](#no-auto-link-without-protocol)
* [no-blockquote-without-caret](#no-blockquote-without-caret)
* [no-consecutive-blank-lines](#no-consecutive-blank-lines)
* [no-duplicate-definitions](#no-duplicate-definitions)
* [no-duplicate-headings](#no-duplicate-headings)
* [no-emphasis-as-heading](#no-emphasis-as-heading)
* [no-file-name-articles](#no-file-name-articles)
* [no-file-name-consecutive-dashes](#no-file-name-consecutive-dashes)
* [no-file-name-irregular-characters](#no-file-name-irregular-characters)
* [no-file-name-mixed-case](#no-file-name-mixed-case)
* [no-file-name-outer-dashes](#no-file-name-outer-dashes)
* [no-heading-content-indent](#no-heading-content-indent)
* [no-heading-indent](#no-heading-indent)
* [no-heading-punctuation](#no-heading-punctuation)
* [no-html](#no-html)
* [no-inline-padding](#no-inline-padding)
* [no-literal-urls](#no-literal-urls)
* [no-missing-blank-lines](#no-missing-blank-lines)
* [no-multiple-toplevel-headings](#no-multiple-toplevel-headings)
* [no-shell-dollars](#no-shell-dollars)
* [no-shortcut-reference-image](#no-shortcut-reference-image)
* [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)
* [rule-style](#rule-style)
* [strong-marker](#strong-marker)
* [table-cell-padding](#table-cell-padding)
* [table-pipe-alignment](#table-pipe-alignment)
* [table-pipes](#table-pipes)
* [unordered-list-marker-style](#unordered-list-marker-style)

## Rules

Remember that rules can always be turned off by
passing false. In addition, when reset is given, values can
be null or undefined in order to be ignored.

### Table of Contents

* [external](#external)
* [reset](#reset)
* [blockquote-indentation](#blockquote-indentation)
* [checkbox-character-style](#checkbox-character-style)
* [checkbox-content-indent](#checkbox-content-indent)
* [code-block-style](#code-block-style)
* [definition-case](#definition-case)
* [definition-spacing](#definition-spacing)
* [emphasis-marker](#emphasis-marker)
* [fenced-code-flag](#fenced-code-flag)
* [fenced-code-marker](#fenced-code-marker)
* [file-extension](#file-extension)
* [final-definition](#final-definition)
* [final-newline](#final-newline)
* [first-heading-level](#first-heading-level)
* [hard-break-spaces](#hard-break-spaces)
* [heading-increment](#heading-increment)
* [heading-style](#heading-style)
* [link-title-style](#link-title-style)
* [list-item-bullet-indent](#list-item-bullet-indent)
* [list-item-content-indent](#list-item-content-indent)
* [list-item-indent](#list-item-indent)
* [list-item-spacing](#list-item-spacing)
* [maximum-heading-length](#maximum-heading-length)
* [maximum-line-length](#maximum-line-length)
* [no-auto-link-without-protocol](#no-auto-link-without-protocol)
* [no-blockquote-without-caret](#no-blockquote-without-caret)
* [no-consecutive-blank-lines](#no-consecutive-blank-lines)
* [no-duplicate-definitions](#no-duplicate-definitions)
* [no-duplicate-headings](#no-duplicate-headings)
* [no-emphasis-as-heading](#no-emphasis-as-heading)
* [no-file-name-articles](#no-file-name-articles)
* [no-file-name-consecutive-dashes](#no-file-name-consecutive-dashes)
* [no-file-name-irregular-characters](#no-file-name-irregular-characters)
* [no-file-name-mixed-case](#no-file-name-mixed-case)
* [no-file-name-outer-dashes](#no-file-name-outer-dashes)
* [no-heading-content-indent](#no-heading-content-indent)
* [no-heading-indent](#no-heading-indent)
* [no-heading-punctuation](#no-heading-punctuation)
* [no-html](#no-html)
* [no-inline-padding](#no-inline-padding)
* [no-literal-urls](#no-literal-urls)
* [no-missing-blank-lines](#no-missing-blank-lines)
* [no-multiple-toplevel-headings](#no-multiple-toplevel-headings)
* [no-shell-dollars](#no-shell-dollars)
* [no-shortcut-reference-image](#no-shortcut-reference-image)
* [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)
* [rule-style](#rule-style)
* [strong-marker](#strong-marker)
* [table-cell-padding](#table-cell-padding)
* [table-pipe-alignment](#table-pipe-alignment)
* [table-pipes](#table-pipes)
* [unordered-list-marker-style](#unordered-list-marker-style)

### external

````md
Expand All @@ -95,6 +94,8 @@ name or a file), but in the browser an object must be passed in.
When using a globally installed remark-lint, globally installed external
rules are also loaded.

The prefix `remark-lint-` can be omitted.

### reset

````md
Expand Down
82 changes: 4 additions & 78 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,38 +24,8 @@ var SOURCE = 'remark-lint';
var decamelize = require('decamelize');
var sort = require('vfile-sort');
var control = require('remark-message-control');
var loadPlugin = require('load-plugin');
var internals = require('./rules');
var npmPrefix = require('npm-prefix')();

/*
* Needed for plug-in resolving.
*/

var path = require('path');
var fs = require('fs');
var exists = fs && fs.existsSync;
var resolve = path && path.resolve;
var isWindows;
var isElectron;
var isGlobal;
var globals;
var cwd;

var MODULES = 'node_modules';

/* istanbul ignore else */
if (typeof global !== 'undefined') {
/* global global */
cwd = global.process.cwd();

/* Detect whether we’re running as a globally installed package. */
isWindows = global.process.platform === 'win32';
isElectron = global.process.versions.electron !== undefined;
isGlobal = isElectron || global.process.argv[1].indexOf(npmPrefix) === 0;

/* istanbul ignore next */
globals = resolve(npmPrefix, isWindows ? '' : 'lib', MODULES);
}

/**
* Factory to create a plugin from a rule.
Expand Down Expand Up @@ -127,52 +97,6 @@ function attachFactory(id, rule, options) {
return attach;
}

/**
* Require an external. Checks, in this order:
*
* - `$cwd/$pathlike`;
* - `$cwd/$pathlike.js`;
* - `$cwd/node_modules/$pathlike`;
* - `$pathlike`.
*
* Where `$cwd` is the current working directory.
*
* When using a globally installed executable, the
* following are also included:
*
* - `$globals/$pathlike`.
*
* Where `$globals` is the directory of globally installed
* npm packages.
*
* @example
* var plugin = findPlugin('foo');
*
* @throws {Error} - Fails when `pathlike` cannot be
* resolved.
* @param {string} pathlike - Reference to external.
* @return {Object} - Result of `require`ing external.
*/
function loadExternal(pathlike) {
var local = resolve(cwd, pathlike);
var current = resolve(cwd, 'node_modules', pathlike);
var globalPath = resolve(globals, pathlike);
var plugin;

if (exists(local) || exists(local + '.js')) {
plugin = local;
/* istanbul ignore else - for globals */
} else if (exists(current)) {
plugin = current;
} else if (isGlobal && exists(globalPath)) {
plugin = globalPath;
} else {
plugin = pathlike;
}

return require(plugin);
}

/**
* Load all externals. Merges them into a single rule
* object.
Expand Down Expand Up @@ -201,7 +125,9 @@ function loadExternals(externals) {
external = mapping[index];

if (typeof external === 'string') {
external = loadExternal(external);
external = loadPlugin(external, {
prefix: 'remark-lint-'
});
}

for (ruleId in external) {
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
],
"dependencies": {
"decamelize": "^1.0.0",
"load-plugin": "^1.1.1",
"mdast-util-heading-style": "^1.0.0",
"mdast-util-to-string": "^1.0.0",
"npm-prefix": "^1.1.1",
Expand Down
2 changes: 1 addition & 1 deletion script/additional.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"example": "<!-- Explicitly activate rules: -->\n```json\n{\n \"reset\": true,\n \"final-newline\": true\n}\n```\n"
},
"external": {
"description": "External contains a list of extra rules to load.\nThese are, or refer to, an object mapping `ruleId`s to rules.\n\nNote that in node.js, a string can be given (a module\nname or a file), but in the browser an object must be passed in.\n\nWhen using a globally installed remark-lint, globally installed external\nrules are also loaded.",
"description": "External contains a list of extra rules to load.\nThese are, or refer to, an object mapping `ruleId`s to rules.\n\nNote that in node.js, a string can be given (a module\nname or a file), but in the browser an object must be passed in.\n\nWhen using a globally installed remark-lint, globally installed external\nrules are also loaded.\n\nThe prefix `remark-lint-` can be omitted.",
"example": "<!-- Load more rules -->\n```json\n{\n \"external\": [\"foo\", \"bar\", \"baz\"]\n}\n```\n"
}
}
22 changes: 11 additions & 11 deletions script/build-rule-documentation.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,42 +104,42 @@ children.push(
);

/*
* Add the table-of-contents heading.
* Add the rules heading.
*/

children.push({
'type': 'heading',
'depth': 2,
'children': [{
'type': 'text',
'value': 'Table of Contents'
'value': 'Rules'
}]
});

/*
* Add the rules heading.
* Add a section on how to turn of rules.
*/

children.push({
'type': 'heading',
'depth': 2,
'type': 'paragraph',
'children': [{
'type': 'text',
'value': 'Rules'
'value': 'Remember that rules can always be turned off by\n' +
'passing false. In addition, when reset is given, values can\n' +
'be null or undefined in order to be ignored.'
}]
});

/*
* Add a section on how to turn of rules.
* Add the table-of-contents heading.
*/

children.push({
'type': 'paragraph',
'type': 'heading',
'depth': 3,
'children': [{
'type': 'text',
'value': 'Remember that rules can always be turned off by\n' +
'passing false. In addition, when reset is given, values can\n' +
'be null or undefined in order to be ignored.'
'value': 'Table of Contents'
}]
});

Expand Down

0 comments on commit 31f82b2

Please sign in to comment.