Skip to content

Commit 31f82b2

Browse files
committed
Add load-plugin to load external rules
1 parent 5a70271 commit 31f82b2

File tree

5 files changed

+81
-153
lines changed

5 files changed

+81
-153
lines changed

doc/rules.md

Lines changed: 64 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -6,75 +6,74 @@ fix their warnings.
66

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

9-
## Table of Contents
10-
11-
* [Rules](#rules)
12-
* [external](#external)
13-
* [reset](#reset)
14-
* [blockquote-indentation](#blockquote-indentation)
15-
* [checkbox-character-style](#checkbox-character-style)
16-
* [checkbox-content-indent](#checkbox-content-indent)
17-
* [code-block-style](#code-block-style)
18-
* [definition-case](#definition-case)
19-
* [definition-spacing](#definition-spacing)
20-
* [emphasis-marker](#emphasis-marker)
21-
* [fenced-code-flag](#fenced-code-flag)
22-
* [fenced-code-marker](#fenced-code-marker)
23-
* [file-extension](#file-extension)
24-
* [final-definition](#final-definition)
25-
* [final-newline](#final-newline)
26-
* [first-heading-level](#first-heading-level)
27-
* [hard-break-spaces](#hard-break-spaces)
28-
* [heading-increment](#heading-increment)
29-
* [heading-style](#heading-style)
30-
* [link-title-style](#link-title-style)
31-
* [list-item-bullet-indent](#list-item-bullet-indent)
32-
* [list-item-content-indent](#list-item-content-indent)
33-
* [list-item-indent](#list-item-indent)
34-
* [list-item-spacing](#list-item-spacing)
35-
* [maximum-heading-length](#maximum-heading-length)
36-
* [maximum-line-length](#maximum-line-length)
37-
* [no-auto-link-without-protocol](#no-auto-link-without-protocol)
38-
* [no-blockquote-without-caret](#no-blockquote-without-caret)
39-
* [no-consecutive-blank-lines](#no-consecutive-blank-lines)
40-
* [no-duplicate-definitions](#no-duplicate-definitions)
41-
* [no-duplicate-headings](#no-duplicate-headings)
42-
* [no-emphasis-as-heading](#no-emphasis-as-heading)
43-
* [no-file-name-articles](#no-file-name-articles)
44-
* [no-file-name-consecutive-dashes](#no-file-name-consecutive-dashes)
45-
* [no-file-name-irregular-characters](#no-file-name-irregular-characters)
46-
* [no-file-name-mixed-case](#no-file-name-mixed-case)
47-
* [no-file-name-outer-dashes](#no-file-name-outer-dashes)
48-
* [no-heading-content-indent](#no-heading-content-indent)
49-
* [no-heading-indent](#no-heading-indent)
50-
* [no-heading-punctuation](#no-heading-punctuation)
51-
* [no-html](#no-html)
52-
* [no-inline-padding](#no-inline-padding)
53-
* [no-literal-urls](#no-literal-urls)
54-
* [no-missing-blank-lines](#no-missing-blank-lines)
55-
* [no-multiple-toplevel-headings](#no-multiple-toplevel-headings)
56-
* [no-shell-dollars](#no-shell-dollars)
57-
* [no-shortcut-reference-image](#no-shortcut-reference-image)
58-
* [no-shortcut-reference-link](#no-shortcut-reference-link)
59-
* [no-table-indentation](#no-table-indentation)
60-
* [no-tabs](#no-tabs)
61-
* [no-undefined-references](#no-undefined-references)
62-
* [no-unused-definitions](#no-unused-definitions)
63-
* [ordered-list-marker-style](#ordered-list-marker-style)
64-
* [ordered-list-marker-value](#ordered-list-marker-value)
65-
* [rule-style](#rule-style)
66-
* [strong-marker](#strong-marker)
67-
* [table-cell-padding](#table-cell-padding)
68-
* [table-pipe-alignment](#table-pipe-alignment)
69-
* [table-pipes](#table-pipes)
70-
* [unordered-list-marker-style](#unordered-list-marker-style)
71-
729
## Rules
7310

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

15+
### Table of Contents
16+
17+
* [external](#external)
18+
* [reset](#reset)
19+
* [blockquote-indentation](#blockquote-indentation)
20+
* [checkbox-character-style](#checkbox-character-style)
21+
* [checkbox-content-indent](#checkbox-content-indent)
22+
* [code-block-style](#code-block-style)
23+
* [definition-case](#definition-case)
24+
* [definition-spacing](#definition-spacing)
25+
* [emphasis-marker](#emphasis-marker)
26+
* [fenced-code-flag](#fenced-code-flag)
27+
* [fenced-code-marker](#fenced-code-marker)
28+
* [file-extension](#file-extension)
29+
* [final-definition](#final-definition)
30+
* [final-newline](#final-newline)
31+
* [first-heading-level](#first-heading-level)
32+
* [hard-break-spaces](#hard-break-spaces)
33+
* [heading-increment](#heading-increment)
34+
* [heading-style](#heading-style)
35+
* [link-title-style](#link-title-style)
36+
* [list-item-bullet-indent](#list-item-bullet-indent)
37+
* [list-item-content-indent](#list-item-content-indent)
38+
* [list-item-indent](#list-item-indent)
39+
* [list-item-spacing](#list-item-spacing)
40+
* [maximum-heading-length](#maximum-heading-length)
41+
* [maximum-line-length](#maximum-line-length)
42+
* [no-auto-link-without-protocol](#no-auto-link-without-protocol)
43+
* [no-blockquote-without-caret](#no-blockquote-without-caret)
44+
* [no-consecutive-blank-lines](#no-consecutive-blank-lines)
45+
* [no-duplicate-definitions](#no-duplicate-definitions)
46+
* [no-duplicate-headings](#no-duplicate-headings)
47+
* [no-emphasis-as-heading](#no-emphasis-as-heading)
48+
* [no-file-name-articles](#no-file-name-articles)
49+
* [no-file-name-consecutive-dashes](#no-file-name-consecutive-dashes)
50+
* [no-file-name-irregular-characters](#no-file-name-irregular-characters)
51+
* [no-file-name-mixed-case](#no-file-name-mixed-case)
52+
* [no-file-name-outer-dashes](#no-file-name-outer-dashes)
53+
* [no-heading-content-indent](#no-heading-content-indent)
54+
* [no-heading-indent](#no-heading-indent)
55+
* [no-heading-punctuation](#no-heading-punctuation)
56+
* [no-html](#no-html)
57+
* [no-inline-padding](#no-inline-padding)
58+
* [no-literal-urls](#no-literal-urls)
59+
* [no-missing-blank-lines](#no-missing-blank-lines)
60+
* [no-multiple-toplevel-headings](#no-multiple-toplevel-headings)
61+
* [no-shell-dollars](#no-shell-dollars)
62+
* [no-shortcut-reference-image](#no-shortcut-reference-image)
63+
* [no-shortcut-reference-link](#no-shortcut-reference-link)
64+
* [no-table-indentation](#no-table-indentation)
65+
* [no-tabs](#no-tabs)
66+
* [no-undefined-references](#no-undefined-references)
67+
* [no-unused-definitions](#no-unused-definitions)
68+
* [ordered-list-marker-style](#ordered-list-marker-style)
69+
* [ordered-list-marker-value](#ordered-list-marker-value)
70+
* [rule-style](#rule-style)
71+
* [strong-marker](#strong-marker)
72+
* [table-cell-padding](#table-cell-padding)
73+
* [table-pipe-alignment](#table-pipe-alignment)
74+
* [table-pipes](#table-pipes)
75+
* [unordered-list-marker-style](#unordered-list-marker-style)
76+
7877
### external
7978

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

97+
The prefix `remark-lint-` can be omitted.
98+
9899
### reset
99100

100101
````md

lib/index.js

Lines changed: 4 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -24,38 +24,8 @@ var SOURCE = 'remark-lint';
2424
var decamelize = require('decamelize');
2525
var sort = require('vfile-sort');
2626
var control = require('remark-message-control');
27+
var loadPlugin = require('load-plugin');
2728
var internals = require('./rules');
28-
var npmPrefix = require('npm-prefix')();
29-
30-
/*
31-
* Needed for plug-in resolving.
32-
*/
33-
34-
var path = require('path');
35-
var fs = require('fs');
36-
var exists = fs && fs.existsSync;
37-
var resolve = path && path.resolve;
38-
var isWindows;
39-
var isElectron;
40-
var isGlobal;
41-
var globals;
42-
var cwd;
43-
44-
var MODULES = 'node_modules';
45-
46-
/* istanbul ignore else */
47-
if (typeof global !== 'undefined') {
48-
/* global global */
49-
cwd = global.process.cwd();
50-
51-
/* Detect whether we’re running as a globally installed package. */
52-
isWindows = global.process.platform === 'win32';
53-
isElectron = global.process.versions.electron !== undefined;
54-
isGlobal = isElectron || global.process.argv[1].indexOf(npmPrefix) === 0;
55-
56-
/* istanbul ignore next */
57-
globals = resolve(npmPrefix, isWindows ? '' : 'lib', MODULES);
58-
}
5929

6030
/**
6131
* Factory to create a plugin from a rule.
@@ -127,52 +97,6 @@ function attachFactory(id, rule, options) {
12797
return attach;
12898
}
12999

130-
/**
131-
* Require an external. Checks, in this order:
132-
*
133-
* - `$cwd/$pathlike`;
134-
* - `$cwd/$pathlike.js`;
135-
* - `$cwd/node_modules/$pathlike`;
136-
* - `$pathlike`.
137-
*
138-
* Where `$cwd` is the current working directory.
139-
*
140-
* When using a globally installed executable, the
141-
* following are also included:
142-
*
143-
* - `$globals/$pathlike`.
144-
*
145-
* Where `$globals` is the directory of globally installed
146-
* npm packages.
147-
*
148-
* @example
149-
* var plugin = findPlugin('foo');
150-
*
151-
* @throws {Error} - Fails when `pathlike` cannot be
152-
* resolved.
153-
* @param {string} pathlike - Reference to external.
154-
* @return {Object} - Result of `require`ing external.
155-
*/
156-
function loadExternal(pathlike) {
157-
var local = resolve(cwd, pathlike);
158-
var current = resolve(cwd, 'node_modules', pathlike);
159-
var globalPath = resolve(globals, pathlike);
160-
var plugin;
161-
162-
if (exists(local) || exists(local + '.js')) {
163-
plugin = local;
164-
/* istanbul ignore else - for globals */
165-
} else if (exists(current)) {
166-
plugin = current;
167-
} else if (isGlobal && exists(globalPath)) {
168-
plugin = globalPath;
169-
} else {
170-
plugin = pathlike;
171-
}
172-
173-
return require(plugin);
174-
}
175-
176100
/**
177101
* Load all externals. Merges them into a single rule
178102
* object.
@@ -201,7 +125,9 @@ function loadExternals(externals) {
201125
external = mapping[index];
202126

203127
if (typeof external === 'string') {
204-
external = loadExternal(external);
128+
external = loadPlugin(external, {
129+
prefix: 'remark-lint-'
130+
});
205131
}
206132

207133
for (ruleId in external) {

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
],
2121
"dependencies": {
2222
"decamelize": "^1.0.0",
23+
"load-plugin": "^1.1.1",
2324
"mdast-util-heading-style": "^1.0.0",
2425
"mdast-util-to-string": "^1.0.0",
2526
"npm-prefix": "^1.1.1",

script/additional.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"example": "<!-- Explicitly activate rules: -->\n```json\n{\n \"reset\": true,\n \"final-newline\": true\n}\n```\n"
55
},
66
"external": {
7-
"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.",
7+
"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.",
88
"example": "<!-- Load more rules -->\n```json\n{\n \"external\": [\"foo\", \"bar\", \"baz\"]\n}\n```\n"
99
}
1010
}

script/build-rule-documentation.js

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -104,42 +104,42 @@ children.push(
104104
);
105105

106106
/*
107-
* Add the table-of-contents heading.
107+
* Add the rules heading.
108108
*/
109109

110110
children.push({
111111
'type': 'heading',
112112
'depth': 2,
113113
'children': [{
114114
'type': 'text',
115-
'value': 'Table of Contents'
115+
'value': 'Rules'
116116
}]
117117
});
118118

119119
/*
120-
* Add the rules heading.
120+
* Add a section on how to turn of rules.
121121
*/
122122

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

132133
/*
133-
* Add a section on how to turn of rules.
134+
* Add the table-of-contents heading.
134135
*/
135136

136137
children.push({
137-
'type': 'paragraph',
138+
'type': 'heading',
139+
'depth': 3,
138140
'children': [{
139141
'type': 'text',
140-
'value': 'Remember that rules can always be turned off by\n' +
141-
'passing false. In addition, when reset is given, values can\n' +
142-
'be null or undefined in order to be ignored.'
142+
'value': 'Table of Contents'
143143
}]
144144
});
145145

0 commit comments

Comments
 (0)