tldr-lint 0.0.13 → 0.0.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +3 -1
- package/README.md +39 -13
- package/lib/tldr-lint-cli.js +21 -30
- package/lib/tldr-lint.js +12 -8
- package/lib/tldr-parser.js +21 -9
- package/package.json +21 -9
package/LICENSE.md
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
The MIT License (MIT)
|
|
2
2
|
|
|
3
|
-
Copyright (c) 2016 Ruben Vereecken
|
|
3
|
+
Copyright (c) 2016 Ruben Vereecken
|
|
4
|
+
Copyright (c) 2016-present The [tldr-pages team](https://github.com/orgs/tldr-pages/people)
|
|
5
|
+
and [contributors](https://github.com/tldr-pages/tldr-lint/graphs/contributors)
|
|
4
6
|
|
|
5
7
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
6
8
|
|
package/README.md
CHANGED
|
@@ -2,17 +2,24 @@
|
|
|
2
2
|
|
|
3
3
|
[![npm version][npm-image]][npm-url]
|
|
4
4
|
[![Build Status][github-actions-image]][github-actions-url]
|
|
5
|
-
[![
|
|
6
|
-
[![Gitter chat][gitter-image]][gitter-url]
|
|
5
|
+
[![Matrix chat][matrix-image]][matrix-url]
|
|
7
6
|
|
|
8
7
|
`tldr-lint` is a linting tool for validating [tldr](https://github.com/tldr-pages/tldr) pages.
|
|
9
8
|
It can also format your pages for you!
|
|
10
9
|
|
|
10
|
+
## Installation
|
|
11
|
+
|
|
12
|
+
`tldr-lint` and its alias `tldrl` can be installed via `npm`:
|
|
13
|
+
|
|
14
|
+
```sh
|
|
15
|
+
npm install --global tldr-lint
|
|
16
|
+
```
|
|
17
|
+
|
|
11
18
|
## Usage
|
|
12
19
|
|
|
13
20
|
It's really simple.
|
|
14
21
|
|
|
15
|
-
```
|
|
22
|
+
```txt
|
|
16
23
|
Usage: tldr-lint [options] <file|dir>
|
|
17
24
|
|
|
18
25
|
Options:
|
|
@@ -20,10 +27,32 @@ Options:
|
|
|
20
27
|
-f, --format also attempt formatting (to stdout, or as specified by -o)
|
|
21
28
|
-o, --output <file> output to formatted file
|
|
22
29
|
-i, --in-place formats in place
|
|
30
|
+
-t, --tabular format errors in a tabular format
|
|
23
31
|
-v, --verbose print verbose output
|
|
24
|
-
-
|
|
32
|
+
-I, --ignore <codes> ignore comma separated tldr-lint error codes (e.g. "TLDR001,TLDR0014")
|
|
33
|
+
-h, --help display help for command
|
|
25
34
|
```
|
|
26
35
|
|
|
36
|
+
### Usage via Docker
|
|
37
|
+
|
|
38
|
+
We provide a Dockerfile for reproducibly building and testing `tldr-lint` even without having NodeJS installed.
|
|
39
|
+
|
|
40
|
+
For building the Docker image, run this command inside the cloned `tldr-lint` repository:
|
|
41
|
+
|
|
42
|
+
`docker build -t tldr-lint .`
|
|
43
|
+
|
|
44
|
+
For running a `tldr-lint` container, you need to mount a volume containing the page(s) you want to lint to the container.
|
|
45
|
+
For checking a single page, run (replacing `{{/path/to/page.md}}` with the path to the page you want to check):
|
|
46
|
+
|
|
47
|
+
`docker run --rm -v {{/path/to/page.md}}:/app/page.md tldr-lint page.md`
|
|
48
|
+
|
|
49
|
+
In order to run the container on a directory, mount this directory as follows:
|
|
50
|
+
|
|
51
|
+
`docker run --rm -v {{/path/to/directory}}:/app/pages tldr-lint pages/`
|
|
52
|
+
|
|
53
|
+
> [!NOTE]
|
|
54
|
+
> For Windows users, specify the full path to the directory or page you want to check along with the `docker run` command above.
|
|
55
|
+
|
|
27
56
|
## Linter errors
|
|
28
57
|
|
|
29
58
|
All of the errors can be found in [`lib/tldr-lint.js`](./lib/tldr-lint.js).
|
|
@@ -49,6 +78,8 @@ TLDR016 | Label for information link should be spelled exactly `More informa
|
|
|
49
78
|
TLDR017 | Information link should be surrounded with angle brackets
|
|
50
79
|
TLDR018 | Page should only include a single information link
|
|
51
80
|
TLDR019 | Page should only include a maximum of 8 examples
|
|
81
|
+
TLDR020 | Label for additional notes should be spelled exactly `Note:` (with a succeeding whitespace)
|
|
82
|
+
TLDR021 | Command example should not begin or end in whitespace
|
|
52
83
|
TLDR101 | Command description probably not properly annotated
|
|
53
84
|
TLDR102 | Example description probably not properly annotated
|
|
54
85
|
TLDR103 | Command example is missing its closing backtick
|
|
@@ -58,18 +89,13 @@ TLDR106 | Page title should start with a hash (`#`)
|
|
|
58
89
|
TLDR107 | File name should end with `.md` extension
|
|
59
90
|
TLDR108 | File name should not contain whitespace
|
|
60
91
|
TLDR109 | File name should be lowercase
|
|
92
|
+
TLDR110 | Command example should not be empty
|
|
61
93
|
|
|
62
94
|
[npm-url]: https://www.npmjs.com/package/tldr-lint
|
|
63
95
|
[npm-image]: https://img.shields.io/npm/v/tldr-lint.svg
|
|
64
96
|
|
|
65
97
|
[github-actions-url]: https://github.com/tldr-pages/tldr-lint/actions
|
|
66
|
-
[github-actions-image]: https://img.shields.io/github/workflow/status/tldr-pages/tldr-lint/
|
|
67
|
-
|
|
68
|
-
[dep-url]: https://david-dm.org/tldr-pages/tldr-lint
|
|
69
|
-
[dep-image]: https://img.shields.io/david/tldr-pages/tldr-lint.svg
|
|
70
|
-
|
|
71
|
-
[dev-dep-url]: https://david-dm.org/tldr-pages/tldr-lint#info=devDependencies
|
|
72
|
-
[dev-dep-image]: https://img.shields.io/david/dev/tldr-pages/tldr-lint.svg
|
|
98
|
+
[github-actions-image]: https://img.shields.io/github/actions/workflow/status/tldr-pages/tldr-lint/test.yml?branch=main
|
|
73
99
|
|
|
74
|
-
[
|
|
75
|
-
[
|
|
100
|
+
[matrix-url]: https://matrix.to/#/#tldr-pages:matrix.org
|
|
101
|
+
[matrix-image]: https://img.shields.io/matrix/tldr-pages:matrix.org?label=chat+on+matrix
|
package/lib/tldr-lint-cli.js
CHANGED
|
@@ -1,18 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
3
|
+
const linter = require('./tldr-lint.js');
|
|
4
|
+
const fs = require('fs');
|
|
5
|
+
const path = require('path');
|
|
6
|
+
const cli = module.exports;
|
|
7
|
+
const util = require('util');
|
|
8
8
|
|
|
9
9
|
cli.writeErrors = function(file, linterResult, args) {
|
|
10
|
-
|
|
11
|
-
if (args.tabular) {
|
|
12
|
-
format = '%s\t%s\t%s\t%s\t';
|
|
13
|
-
} else {
|
|
14
|
-
format = '%s:%s: %s %s';
|
|
15
|
-
}
|
|
10
|
+
const format = args.tabular ? '%s\t%s\t%s\t%s\t' : '%s:%s: %s %s';
|
|
16
11
|
linterResult.errors.forEach(function(error) {
|
|
17
12
|
console.error(util.format(format, file, (error.locinfo.first_line ||
|
|
18
13
|
error.locinfo.last_line - 1),
|
|
@@ -22,8 +17,8 @@ cli.writeErrors = function(file, linterResult, args) {
|
|
|
22
17
|
if (!linterResult.success) {
|
|
23
18
|
console.error('Refraining from formatting because of fatal error');
|
|
24
19
|
} else {
|
|
25
|
-
|
|
26
|
-
|
|
20
|
+
const formattedPage = linterResult.formatted;
|
|
21
|
+
let err;
|
|
27
22
|
if (args.output) {
|
|
28
23
|
err = fs.writeFileSync(args.output, formattedPage, 'utf8');
|
|
29
24
|
if (err) throw err;
|
|
@@ -38,15 +33,15 @@ cli.writeErrors = function(file, linterResult, args) {
|
|
|
38
33
|
};
|
|
39
34
|
|
|
40
35
|
cli.processFile = function(file, args) {
|
|
41
|
-
|
|
36
|
+
const linterResult = linter.processFile(file, args.verbose, args.format, args.ignore);
|
|
42
37
|
cli.writeErrors(file, linterResult, args);
|
|
43
38
|
return linterResult;
|
|
44
39
|
};
|
|
45
40
|
|
|
46
41
|
cli.processDirectory = function(dir, args) {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
42
|
+
const files = fs.readdirSync(dir);
|
|
43
|
+
let stats;
|
|
44
|
+
const result = {
|
|
50
45
|
success: true,
|
|
51
46
|
errors: []
|
|
52
47
|
};
|
|
@@ -61,11 +56,11 @@ cli.processDirectory = function(dir, args) {
|
|
|
61
56
|
if (stats.isFile()) {
|
|
62
57
|
// Only treat files ending in .md
|
|
63
58
|
if (!file.match(/\.md$/)) return;
|
|
64
|
-
|
|
59
|
+
const linterResult = cli.processFile(file, args);
|
|
65
60
|
result.success &= linterResult.success;
|
|
66
61
|
result.errors = result.errors.concat(linterResult.errors);
|
|
67
62
|
} else {
|
|
68
|
-
|
|
63
|
+
const aggregateResult = cli.processDirectory(file, args);
|
|
69
64
|
result.success &= aggregateResult.success;
|
|
70
65
|
result.errors = result.errors.concat(aggregateResult.errors);
|
|
71
66
|
}
|
|
@@ -78,28 +73,24 @@ cli.process = function(file, args) {
|
|
|
78
73
|
console.error('--output only makes sense when used with --format');
|
|
79
74
|
process.exit(1);
|
|
80
75
|
}
|
|
76
|
+
let stats;
|
|
81
77
|
try {
|
|
82
|
-
|
|
78
|
+
stats = fs.statSync(file);
|
|
83
79
|
} catch(err) {
|
|
84
80
|
console.error(err.toString());
|
|
85
81
|
process.exit(1);
|
|
86
82
|
}
|
|
87
|
-
|
|
83
|
+
const isdir = stats.isDirectory();
|
|
88
84
|
if (args.output && isdir) {
|
|
89
85
|
console.error('--output only makes sense when used with a file');
|
|
90
86
|
}
|
|
91
|
-
|
|
92
|
-
if (!isdir) {
|
|
93
|
-
result = cli.processFile(file, args);
|
|
94
|
-
} else {
|
|
95
|
-
result = cli.processDirectory(file, args);
|
|
96
|
-
}
|
|
87
|
+
const result = isdir ? cli.processDirectory(file, args) : cli.processFile(file, args);
|
|
97
88
|
if (!result.success || result.errors.length >= 1) return process.exit(1);
|
|
98
89
|
};
|
|
99
90
|
|
|
100
91
|
if (require.main === module) {
|
|
101
|
-
|
|
102
|
-
|
|
92
|
+
const { program } = require('commander');
|
|
93
|
+
const package = require('../package.json');
|
|
103
94
|
program
|
|
104
95
|
.version(package.version)
|
|
105
96
|
.description(package.description)
|
|
@@ -109,7 +100,7 @@ if (require.main === module) {
|
|
|
109
100
|
.option('-i, --in-place', 'formats in place')
|
|
110
101
|
.option('-t, --tabular', 'format errors in a tabular format')
|
|
111
102
|
.option('-v, --verbose', 'print verbose output')
|
|
112
|
-
.option('-
|
|
103
|
+
.option('-I, --ignore <codes>', 'ignore comma separated tldr-lint error codes (e.g. "TLDR001,TLDR0014")')
|
|
113
104
|
.parse(process.argv);
|
|
114
105
|
|
|
115
106
|
if (program.args.length !== 1) {
|
package/lib/tldr-lint.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const parser = require('./tldr-parser.js').parser;
|
|
4
|
+
const util = require('util');
|
|
5
5
|
|
|
6
6
|
const MAX_EXAMPLES = 8;
|
|
7
7
|
|
|
@@ -25,6 +25,9 @@ module.exports.ERRORS = parser.ERRORS = {
|
|
|
25
25
|
'TLDR017': 'Information link should be surrounded with angle brackets',
|
|
26
26
|
'TLDR018': 'Page should only include a single information link',
|
|
27
27
|
'TLDR019': 'Page should only include a maximum of 8 examples',
|
|
28
|
+
'TLDR020': 'Label for additional notes should be spelled exactly `Note: `',
|
|
29
|
+
'TLDR021': 'Command example should not begin or end in whitespace',
|
|
30
|
+
|
|
28
31
|
|
|
29
32
|
'TLDR101': 'Command description probably not properly annotated',
|
|
30
33
|
'TLDR102': 'Example description probably not properly annotated',
|
|
@@ -35,6 +38,7 @@ module.exports.ERRORS = parser.ERRORS = {
|
|
|
35
38
|
'TLDR107': 'File name should end with .md extension',
|
|
36
39
|
'TLDR108': 'File name should not contain whitespace',
|
|
37
40
|
'TLDR109': 'File name should be lowercase',
|
|
41
|
+
'TLDR110': 'Command example should not be empty',
|
|
38
42
|
};
|
|
39
43
|
|
|
40
44
|
(function(parser) {
|
|
@@ -117,7 +121,7 @@ module.exports.ERRORS = parser.ERRORS = {
|
|
|
117
121
|
};
|
|
118
122
|
})(parser);
|
|
119
123
|
|
|
120
|
-
|
|
124
|
+
const linter = module.exports;
|
|
121
125
|
|
|
122
126
|
linter.parse = function(page) {
|
|
123
127
|
parser.init();
|
|
@@ -135,7 +139,7 @@ linter.formatExampleDescription = function(str) {
|
|
|
135
139
|
};
|
|
136
140
|
|
|
137
141
|
linter.format = function(parsedPage) {
|
|
138
|
-
|
|
142
|
+
let str = '';
|
|
139
143
|
str += util.format('# %s', parsedPage.title);
|
|
140
144
|
str += '\n\n';
|
|
141
145
|
parsedPage.description.forEach(function(line) {
|
|
@@ -163,7 +167,7 @@ linter.format = function(parsedPage) {
|
|
|
163
167
|
};
|
|
164
168
|
|
|
165
169
|
linter.process = function(file, page, verbose, alsoFormat) {
|
|
166
|
-
|
|
170
|
+
let success, result;
|
|
167
171
|
try {
|
|
168
172
|
linter.parse(page);
|
|
169
173
|
success = true;
|
|
@@ -195,7 +199,7 @@ linter.process = function(file, page, verbose, alsoFormat) {
|
|
|
195
199
|
};
|
|
196
200
|
|
|
197
201
|
linter.processFile = function(file, verbose, alsoFormat, ignoreErrors) {
|
|
198
|
-
|
|
202
|
+
const result = linter.process(file, fs.readFileSync(file, 'utf8'), verbose, alsoFormat);
|
|
199
203
|
if (path.extname(file) !== '.md') {
|
|
200
204
|
result.errors.push({ locinfo: { first_line: '0' }, code: 'TLDR107', description: this.ERRORS.TLDR107 });
|
|
201
205
|
}
|
package/lib/tldr-parser.js
CHANGED
|
@@ -77,7 +77,7 @@ var parser = {trace: function trace () { },
|
|
|
77
77
|
yy: {},
|
|
78
78
|
symbols_: {"error":2,"page":3,"title":4,"NEWLINE":5,"info":6,"examples":7,"TEXT":8,"HASH":9,"TITLE":10,"description":11,"information_link":12,"GREATER_THAN":13,"DESCRIPTION_LINE":14,"INFORMATION_LINK":15,"ANGLE_BRACKETED_URL":16,"END_INFORMATION_LINK_URL":17,"END_INFORMATION_LINK":18,"example":19,"maybe_newline":20,"example_description":21,"example_commands":22,"DASH":23,"EXAMPLE_DESCRIPTION":24,"example_command":25,"BACKTICK":26,"example_command_inner":27,"COMMAND_TEXT":28,"COMMAND_TOKEN":29,"$accept":0,"$end":1},
|
|
79
79
|
terminals_: {2:"error",5:"NEWLINE",8:"TEXT",9:"HASH",10:"TITLE",13:"GREATER_THAN",14:"DESCRIPTION_LINE",15:"INFORMATION_LINK",16:"ANGLE_BRACKETED_URL",17:"END_INFORMATION_LINK_URL",18:"END_INFORMATION_LINK",23:"DASH",24:"EXAMPLE_DESCRIPTION",26:"BACKTICK",28:"COMMAND_TEXT",29:"COMMAND_TOKEN"},
|
|
80
|
-
productions_: [0,[3,4],[3,3],[3,4],[4,2],[4,1],[6,1],[6,2],[11,2],[11,3],[12,4],[12,3],[12,5],[7,0],[7,2],[19,4],[20,0],[20,1],[21,2],[21,1],[22,1],[22,2],[25,3],[27,
|
|
80
|
+
productions_: [0,[3,4],[3,3],[3,4],[4,2],[4,1],[6,1],[6,2],[11,2],[11,3],[12,4],[12,3],[12,5],[7,0],[7,2],[19,4],[20,0],[20,1],[21,2],[21,1],[22,1],[22,2],[25,2],[25,3],[27,1],[27,1],[27,2],[27,2]],
|
|
81
81
|
performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate /* action[1] */, $$ /* vstack */, _$ /* lstack */) {
|
|
82
82
|
/* this == yyval */
|
|
83
83
|
|
|
@@ -117,7 +117,7 @@ case 15:
|
|
|
117
117
|
yy.error(_$[$0], 'TLDR007');
|
|
118
118
|
|
|
119
119
|
break;
|
|
120
|
-
case 18:
|
|
120
|
+
case 18: case 24: case 25:
|
|
121
121
|
this.$ = $$[$0];
|
|
122
122
|
break;
|
|
123
123
|
case 19:
|
|
@@ -130,20 +130,20 @@ case 21:
|
|
|
130
130
|
this.$ = yy.error(_$[$0], 'TLDR105') || $$[$0-1];
|
|
131
131
|
break;
|
|
132
132
|
case 22:
|
|
133
|
-
this.$ =
|
|
133
|
+
this.$ = yy.error(this._$, 'TLDR110');
|
|
134
134
|
break;
|
|
135
135
|
case 23:
|
|
136
|
-
this.$ = [];
|
|
136
|
+
this.$ = $$[$0-1];
|
|
137
137
|
break;
|
|
138
|
-
case
|
|
138
|
+
case 26:
|
|
139
139
|
this.$ = [].concat($$[$0-1], yy.createCommandText($$[$0]));
|
|
140
140
|
break;
|
|
141
|
-
case
|
|
141
|
+
case 27:
|
|
142
142
|
this.$ = [].concat($$[$0-1], yy.createToken($$[$0]));
|
|
143
143
|
break;
|
|
144
144
|
}
|
|
145
145
|
},
|
|
146
|
-
table: [{3:1,4:2,8:[1,4],9:[1,3]},{1:[3]},{5:[1,5],6:6,11:7,13:$V0},{10:[1,9]},o($V1,[2,5]),{6:10,8:[1,11],11:7,13:$V0},o($V2,$V3,{7:12}),o($V2,[2,6],{12:13,13:[1,14]}),{14:[1,15]},o($V1,[2,4]),o($V2,$V3,{7:16}),o($V2,$V3,{7:17}),o($V4,$V5,{19:18,20:19,1:[2,2],5:$V6}),o($V2,[2,7],{13:[1,21]}),{14:[1,22],15:[1,23]},o($V7,[2,8]),o($V4,$V5,{19:18,20:19,1:[2,1],5:$V6}),o($V4,$V5,{19:18,20:19,1:[2,3],5:$V6}),o($V2,[2,14]),{8:[1,26],21:24,23:[1,25]},o([8,23,26],[2,17]),{15:[1,27]},o($V7,[2,9]),{16:[1,28],18:[1,29]},{5:$V6,20:30,26:$V5},{24:[1,31]},o($V8,[2,19]),{16:[1,32]},{17:[1,33]},o($V7,[2,11]),{22:34,25:35,26:$V9},o($V8,[2,18]),{17:[1,37]},o($V7,[2,10]),o($V2,[2,15],{25:38,26:$V9}),o($Va,[2,20]),
|
|
146
|
+
table: [{3:1,4:2,8:[1,4],9:[1,3]},{1:[3]},{5:[1,5],6:6,11:7,13:$V0},{10:[1,9]},o($V1,[2,5]),{6:10,8:[1,11],11:7,13:$V0},o($V2,$V3,{7:12}),o($V2,[2,6],{12:13,13:[1,14]}),{14:[1,15]},o($V1,[2,4]),o($V2,$V3,{7:16}),o($V2,$V3,{7:17}),o($V4,$V5,{19:18,20:19,1:[2,2],5:$V6}),o($V2,[2,7],{13:[1,21]}),{14:[1,22],15:[1,23]},o($V7,[2,8]),o($V4,$V5,{19:18,20:19,1:[2,1],5:$V6}),o($V4,$V5,{19:18,20:19,1:[2,3],5:$V6}),o($V2,[2,14]),{8:[1,26],21:24,23:[1,25]},o([8,23,26],[2,17]),{15:[1,27]},o($V7,[2,9]),{16:[1,28],18:[1,29]},{5:$V6,20:30,26:$V5},{24:[1,31]},o($V8,[2,19]),{16:[1,32]},{17:[1,33]},o($V7,[2,11]),{22:34,25:35,26:$V9},o($V8,[2,18]),{17:[1,37]},o($V7,[2,10]),o($V2,[2,15],{25:38,26:$V9}),o($Va,[2,20]),{26:[1,39],27:40,28:[1,41],29:[1,42]},o($V7,[2,12]),o($Va,[2,21]),o($Va,[2,22]),{26:[1,43],28:[1,44],29:[1,45]},o($Vb,[2,24]),o($Vb,[2,25]),o($Va,[2,23]),o($Vb,[2,26]),o($Vb,[2,27])],
|
|
147
147
|
defaultActions: {},
|
|
148
148
|
parseError: function parseError (str, hash) {
|
|
149
149
|
if (hash.recoverable) {
|
|
@@ -729,12 +729,15 @@ case 8:
|
|
|
729
729
|
if (!exceptions.includes(yy_.yytext.replace(/ .*/,'')) && yy_.yytext.match(/^[a-z]/)) {
|
|
730
730
|
yy.error(yy_.yylloc, 'TLDR003');
|
|
731
731
|
}
|
|
732
|
+
if (yy_.yytext.match(/(note|NOTE): /)) {
|
|
733
|
+
yy.error(yy_.yylloc, 'TLDR020');
|
|
734
|
+
}
|
|
732
735
|
var punctuation = this.matches[2];
|
|
733
736
|
if (punctuation !== '.') {
|
|
734
737
|
yy.error(yy_.yylloc, 'TLDR004');
|
|
735
738
|
}
|
|
736
739
|
if (punctuation.match(/[,;]/)) {
|
|
737
|
-
console.warn(
|
|
740
|
+
console.warn(`Description ends in \'${punctuation}\'. Consider writing your sentence on one line.`);
|
|
738
741
|
}
|
|
739
742
|
this.checkTrailingWhitespace(this.matches[3], yy_.yylloc);
|
|
740
743
|
this.checkNewline(this.matches[4], yy_.yylloc);
|
|
@@ -750,6 +753,9 @@ case 9:
|
|
|
750
753
|
yy_.yytext = this.matches[1];
|
|
751
754
|
if (!yy_.yytext.match(/^[\p{Lu}\[]/u)) yy.error(yy_.yylloc, 'TLDR015');
|
|
752
755
|
if (this.matches[2] !== ':') yy.error(yy_.yylloc, 'TLDR005');
|
|
756
|
+
if (yy_.yytext.match(/(note|NOTE): /)) {
|
|
757
|
+
yy.error(yy_.yylloc, 'TLDR020');
|
|
758
|
+
}
|
|
753
759
|
// Try to ensure that verbs at the beginning of the description are in the infinitive tense
|
|
754
760
|
// 1. Any word at the start of a sentence that ends with "ing" and is 6 or more characters long (e.g. executing, writing) is likely a verb in the gerund
|
|
755
761
|
// 2. Any word at the start of a sentence that doesn't end with "us", "ss", or "ys" (e.g. superfluous, success, always) is likely a verb in the present tense
|
|
@@ -777,6 +783,9 @@ case 10:
|
|
|
777
783
|
break;
|
|
778
784
|
case 11:
|
|
779
785
|
this.pushState('example_command');
|
|
786
|
+
if (this.matches[1].match(/ /)) {
|
|
787
|
+
yy.error(yy_.yylloc, 'TLDR021')
|
|
788
|
+
}
|
|
780
789
|
return 26;
|
|
781
790
|
|
|
782
791
|
break;
|
|
@@ -807,6 +816,9 @@ case 14:
|
|
|
807
816
|
if (this.matches[2].match(/ /)) {
|
|
808
817
|
yy.error(yy_.yylloc, 'TLDR014');
|
|
809
818
|
}
|
|
819
|
+
if (this.matches[1].endsWith(' ') && !this.matches[1].endsWith('\\ ')) {
|
|
820
|
+
yy.error(yy_.yylloc, 'TLDR021');
|
|
821
|
+
}
|
|
810
822
|
// Don't swallow the trailing backtick just yet
|
|
811
823
|
if (this.matches[2].match(/\`/)) this.unput('`');
|
|
812
824
|
else {
|
|
@@ -841,7 +853,7 @@ case 17:
|
|
|
841
853
|
break;
|
|
842
854
|
}
|
|
843
855
|
},
|
|
844
|
-
rules: [/^(?:\s+$)/,/^(?:.*?\t+.*)/,/^(?:[^\n]$)/,/^(?:(\s*)#(\s*))/,/^(?:([\>-])(\s*))/,/^(?:([Mm]ore\s+[Ii]nfo(?:rmation)?:?\s*))/,/^(?:(<https?:\/\/[^\s\>]*>))/,/^(?:(.+?)([ ]*)((?:\r\n)|\n|\r))/,/^(?:(.+?)([\.,;!\?]?)([ ]*)((?:\r\n)|\n|\r))/,/^(?:(.+?)([\.:,;]?)([ ]*)((?:\r\n)|\n|\r))/,/^(?:`((?:\r\n)|\n|\r))/,/^(?:`)/,/^(?:\{\{([^\n\`\{\}]*)\}\}(((?:\r\n)|\n|\r)?))/,/^(?:([^\`\n]+?)\{\{)/,/^(?:([^\`\n]+?)(`[ ]*|[ ]*((?:\r\n)|\n|\r)))/,/^(?:[ ]+)/,/^(?:((?:\r\n)|\n|\r)+)/,/^(?:(.+?)[\.:]?((?:\r\n)|\n|\r))/],
|
|
856
|
+
rules: [/^(?:\s+$)/,/^(?:.*?\t+.*)/,/^(?:[^\n]$)/,/^(?:(\s*)#(\s*))/,/^(?:([\>-])(\s*))/,/^(?:([Mm]ore\s+[Ii]nfo(?:rmation)?:?\s*))/,/^(?:(<https?:\/\/[^\s\>]*>))/,/^(?:(.+?)([ ]*)((?:\r\n)|\n|\r))/,/^(?:(.+?)([\.,;!\?]?)([ ]*)((?:\r\n)|\n|\r))/,/^(?:(.+?)([\.:,;]?)([ ]*)((?:\r\n)|\n|\r))/,/^(?:`((?:\r\n)|\n|\r))/,/^(?:`([ ]*))/,/^(?:\{\{([^\n\`\{\}]*)\}\}(((?:\r\n)|\n|\r)?))/,/^(?:([^\`\n]+?)\{\{)/,/^(?:([^\`\n]+?)(`[ ]*|[ ]*((?:\r\n)|\n|\r)))/,/^(?:[ ]+)/,/^(?:((?:\r\n)|\n|\r)+)/,/^(?:(.+?)[\.:]?((?:\r\n)|\n|\r))/],
|
|
845
857
|
conditions: {"INITIAL":{"rules":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17],"inclusive":true}}
|
|
846
858
|
});
|
|
847
859
|
return lexer;
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tldr-lint",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.15",
|
|
4
4
|
"description": "A linting tool to validate tldr pages",
|
|
5
5
|
"repository": "tldr-pages/tldr-lint",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"jison": "jison tldr.yy tldr.l -o lib/tldr-parser.js",
|
|
8
8
|
"lint": "eslint lib specs",
|
|
9
|
-
"prepare": "husky
|
|
10
|
-
"test": "
|
|
9
|
+
"prepare": "husky",
|
|
10
|
+
"test": "jest specs",
|
|
11
11
|
"watch": "concurrently 'npm run watch:jison' 'npm run watch:specs'",
|
|
12
12
|
"watch:jison": "onchange '*.l' '*.yy' -- npm run jison",
|
|
13
13
|
"watch:specs": "onchange 'specs/*.js' 'lib/*.js' '*.l' '*.yy' -- npm run test"
|
|
@@ -27,19 +27,31 @@
|
|
|
27
27
|
"name": "Ruben Vereecken",
|
|
28
28
|
"email": "rubenvereecken@gmail.com"
|
|
29
29
|
},
|
|
30
|
+
"maintainers": [
|
|
31
|
+
{
|
|
32
|
+
"name": "tldr-pages team"
|
|
33
|
+
}
|
|
34
|
+
],
|
|
35
|
+
"engines": {
|
|
36
|
+
"node": ">=18"
|
|
37
|
+
},
|
|
30
38
|
"license": "MIT",
|
|
31
39
|
"dependencies": {
|
|
32
|
-
"commander": "^
|
|
40
|
+
"commander": "^12.0.0"
|
|
33
41
|
},
|
|
34
42
|
"devDependencies": {
|
|
35
|
-
"concurrently": "^
|
|
36
|
-
"eslint": "^
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
"
|
|
43
|
+
"concurrently": "^8.0.1",
|
|
44
|
+
"eslint": "^8.0.0",
|
|
45
|
+
"eslint-plugin-jest": "^27.0.4",
|
|
46
|
+
"husky": "^9.0.6",
|
|
47
|
+
"jest": "^29.1.2",
|
|
40
48
|
"jison": "^0.4.18",
|
|
41
49
|
"onchange": "^7.1.0"
|
|
42
50
|
},
|
|
51
|
+
"funding": {
|
|
52
|
+
"type": "liberapay",
|
|
53
|
+
"url": "https://liberapay.com/tldr-pages"
|
|
54
|
+
},
|
|
43
55
|
"files": [
|
|
44
56
|
"lib/"
|
|
45
57
|
]
|