tldr-lint 0.0.19 → 0.0.21
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/README.md +1 -0
- package/lib/tldr-lint.js +3 -3
- package/lib/tldr-parser.js +52 -2
- package/package.json +7 -5
package/README.md
CHANGED
|
@@ -91,6 +91,7 @@ TLDR108 | File name should not contain whitespace
|
|
|
91
91
|
TLDR109 | File name should be lowercase
|
|
92
92
|
TLDR110 | Command example should not be empty
|
|
93
93
|
TLDR111 | File name should not contain any Windows-forbidden character
|
|
94
|
+
TLDR112 | Terms `stdin`, `stdout`, `stderr`, and `regex` (including longer forms like "standard input", "regular expression") should be lowercase and wrapped in backticks
|
|
94
95
|
|
|
95
96
|
[npm-url]: https://www.npmjs.com/package/tldr-lint
|
|
96
97
|
[npm-image]: https://img.shields.io/npm/v/tldr-lint.svg
|
package/lib/tldr-lint.js
CHANGED
|
@@ -18,7 +18,7 @@ module.exports.ERRORS = parser.ERRORS = {
|
|
|
18
18
|
'TLDR010': 'Only Unix-style line endings allowed',
|
|
19
19
|
'TLDR011': 'Page never contains more than a single empty line',
|
|
20
20
|
'TLDR012': 'Page should contain no tabs',
|
|
21
|
-
'TLDR013': 'Title should be alphanumeric with dashes, underscores or
|
|
21
|
+
'TLDR013': 'Title should be alphanumeric with dashes, underscores, spaces or allowed characters',
|
|
22
22
|
'TLDR014': 'Page should contain no trailing whitespace',
|
|
23
23
|
'TLDR015': 'Example descriptions should start with a capital letter',
|
|
24
24
|
'TLDR016': 'Label for information link should be spelled exactly `More information: `',
|
|
@@ -39,7 +39,8 @@ module.exports.ERRORS = parser.ERRORS = {
|
|
|
39
39
|
'TLDR108': 'File name should not contain whitespace',
|
|
40
40
|
'TLDR109': 'File name should be lowercase',
|
|
41
41
|
'TLDR110': 'Command example should not be empty',
|
|
42
|
-
'TLDR111': 'File name should not contain any Windows-forbidden character'
|
|
42
|
+
'TLDR111': 'File name should not contain any Windows-forbidden character',
|
|
43
|
+
'TLDR112': 'Terms `stdin`, `stdout`, `stderr`, and `regex` should be lowercase and wrapped in backticks'
|
|
43
44
|
};
|
|
44
45
|
|
|
45
46
|
(function(parser) {
|
|
@@ -156,7 +157,6 @@ linter.format = function(parsedPage) {
|
|
|
156
157
|
str += util.format('- %s', linter.formatExampleDescription(example.description));
|
|
157
158
|
str += '\n\n';
|
|
158
159
|
example.commands.forEach(function(command) {
|
|
159
|
-
|
|
160
160
|
str += '`';
|
|
161
161
|
command.forEach(function(textOrToken) {
|
|
162
162
|
str += textOrToken.type === 'token' ? util.format('{{%s}}', textOrToken.content) : textOrToken.content;
|
package/lib/tldr-parser.js
CHANGED
|
@@ -117,7 +117,7 @@ case 15:
|
|
|
117
117
|
yy.error(_$[$0], 'TLDR007');
|
|
118
118
|
|
|
119
119
|
break;
|
|
120
|
-
case 18:
|
|
120
|
+
case 18:
|
|
121
121
|
this.$ = $$[$0];
|
|
122
122
|
break;
|
|
123
123
|
case 19:
|
|
@@ -135,6 +135,12 @@ break;
|
|
|
135
135
|
case 23:
|
|
136
136
|
this.$ = $$[$0-1];
|
|
137
137
|
break;
|
|
138
|
+
case 24:
|
|
139
|
+
this.$ = [yy.createCommandText($$[$0])];
|
|
140
|
+
break;
|
|
141
|
+
case 25:
|
|
142
|
+
this.$ = [yy.createToken($$[$0])];
|
|
143
|
+
break;
|
|
138
144
|
case 26:
|
|
139
145
|
this.$ = [].concat($$[$0-1], yy.createCommandText($$[$0]));
|
|
140
146
|
break;
|
|
@@ -701,7 +707,7 @@ case 7:
|
|
|
701
707
|
if (this.topState() === "title") {
|
|
702
708
|
yy_.yytext = this.matches[1];
|
|
703
709
|
if (
|
|
704
|
-
/[^\w+\[\]{}
|
|
710
|
+
/[^\w+\[\]{}!%,^~$:><|?. -]/.test(yy_.yytext) ||
|
|
705
711
|
(yy_.yytext.endsWith('.') && yy_.yytext !== '.' && yy_.yytext !== ' .')
|
|
706
712
|
) {
|
|
707
713
|
yy.error(yy_.yylloc, 'TLDR013');
|
|
@@ -744,6 +750,28 @@ case 8:
|
|
|
744
750
|
if (punctuation.match(/[,;]/)) {
|
|
745
751
|
console.warn(`Description ends in \'${punctuation}\'. Consider writing your sentence on one line.`);
|
|
746
752
|
}
|
|
753
|
+
// Check for incorrect stdout/stdin/stderr/regex usage
|
|
754
|
+
var termMatch = yy_.yytext.match(/(?:^|[^`-\w])(stdout|stdin|stderr|regex|regular\s+expression|standard\s+(?:in|input|out|output|err|error))(?=[^`\w]|$)/i);
|
|
755
|
+
if (termMatch) {
|
|
756
|
+
// Skip if the term is inside angle brackets (URL)
|
|
757
|
+
var beforeTerm = yy_.yytext.substring(0, termMatch.index + termMatch[0].indexOf(termMatch[1]));
|
|
758
|
+
var afterTerm = yy_.yytext.substring(termMatch.index + termMatch[0].indexOf(termMatch[1]) + termMatch[1].length);
|
|
759
|
+
var insideUrl = (beforeTerm.lastIndexOf('<') > beforeTerm.lastIndexOf('>')) && (afterTerm.indexOf('>') < afterTerm.indexOf('<') || afterTerm.indexOf('<') === -1);
|
|
760
|
+
if (!insideUrl) {
|
|
761
|
+
var foundTerm = termMatch[1].toLowerCase();
|
|
762
|
+
var term = foundTerm;
|
|
763
|
+
// Map longer forms to shorter forms
|
|
764
|
+
if (foundTerm === 'regular expression') term = 'regex';
|
|
765
|
+
else if (foundTerm.match(/^standard (in|input)$/)) term = 'stdin';
|
|
766
|
+
else if (foundTerm.match(/^standard (out|output)$/)) term = 'stdout';
|
|
767
|
+
else if (foundTerm.match(/^standard (err|error)$/)) term = 'stderr';
|
|
768
|
+
yy.errors.push({
|
|
769
|
+
locinfo: yy_.yylloc,
|
|
770
|
+
code: 'TLDR112',
|
|
771
|
+
description: 'Term `' + termMatch[1] + '` should be lowercase and wrapped in backticks (`' + term + '`)'
|
|
772
|
+
});
|
|
773
|
+
}
|
|
774
|
+
}
|
|
747
775
|
this.checkTrailingWhitespace(this.matches[3], yy_.yylloc);
|
|
748
776
|
this.checkNewline(this.matches[4], yy_.yylloc);
|
|
749
777
|
return 14;
|
|
@@ -767,6 +795,28 @@ case 9:
|
|
|
767
795
|
if (yy_.yytext.match(/(^[A-Za-z]{3,}ing )|(^[A-Za-z]+[^usy]s )/)) {
|
|
768
796
|
yy.error(yy_.yylloc, 'TLDR104');
|
|
769
797
|
}
|
|
798
|
+
// Check for incorrect stdout/stdin/stderr/regex usage
|
|
799
|
+
var termMatch = yy_.yytext.match(/(?:^|[^`-\w])(stdout|stdin|stderr|regex|regular\s+expression|standard\s+(?:in|input|out|output|err|error))(?=[^`\w]|$)/i);
|
|
800
|
+
if (termMatch) {
|
|
801
|
+
// Skip if the term is inside angle brackets (URL)
|
|
802
|
+
var beforeTerm = yy_.yytext.substring(0, termMatch.index + termMatch[0].indexOf(termMatch[1]));
|
|
803
|
+
var afterTerm = yy_.yytext.substring(termMatch.index + termMatch[0].indexOf(termMatch[1]) + termMatch[1].length);
|
|
804
|
+
var insideUrl = (beforeTerm.lastIndexOf('<') > beforeTerm.lastIndexOf('>')) && (afterTerm.indexOf('>') < afterTerm.indexOf('<') || afterTerm.indexOf('<') === -1);
|
|
805
|
+
if (!insideUrl) {
|
|
806
|
+
var foundTerm = termMatch[1].toLowerCase();
|
|
807
|
+
var term = foundTerm;
|
|
808
|
+
// Map longer forms to shorter forms
|
|
809
|
+
if (foundTerm === 'regular expression') term = 'regex';
|
|
810
|
+
else if (foundTerm.match(/^standard (in|input)$/)) term = 'stdin';
|
|
811
|
+
else if (foundTerm.match(/^standard (out|output)$/)) term = 'stdout';
|
|
812
|
+
else if (foundTerm.match(/^standard (err|error)$/)) term = 'stderr';
|
|
813
|
+
yy.errors.push({
|
|
814
|
+
locinfo: yy_.yylloc,
|
|
815
|
+
code: 'TLDR112',
|
|
816
|
+
description: 'Term `' + termMatch[1] + '` should be lowercase and wrapped in backticks (`' + term + '`)'
|
|
817
|
+
});
|
|
818
|
+
}
|
|
819
|
+
}
|
|
770
820
|
// Check if any sneaky spaces have been caught
|
|
771
821
|
this.checkTrailingWhitespace(this.matches[3], yy_.yylloc);
|
|
772
822
|
this.checkNewline(this.matches[3], yy_.yylloc);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tldr-lint",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.21",
|
|
4
4
|
"description": "A linting tool to validate tldr pages",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -24,8 +24,10 @@
|
|
|
24
24
|
"pages",
|
|
25
25
|
"lint",
|
|
26
26
|
"validate",
|
|
27
|
-
"format"
|
|
27
|
+
"format",
|
|
28
|
+
"linter"
|
|
28
29
|
],
|
|
30
|
+
"homepage": "https://tldr.sh",
|
|
29
31
|
"author": {
|
|
30
32
|
"name": "Ruben Vereecken",
|
|
31
33
|
"email": "rubenvereecken@gmail.com"
|
|
@@ -45,10 +47,10 @@
|
|
|
45
47
|
"devDependencies": {
|
|
46
48
|
"concurrently": "^9.1.2",
|
|
47
49
|
"eslint": "^9.17.0",
|
|
48
|
-
"eslint-config-eslint": "^
|
|
49
|
-
"eslint-plugin-jest": "^
|
|
50
|
+
"eslint-config-eslint": "^13.0.0",
|
|
51
|
+
"eslint-plugin-jest": "^29.0.1",
|
|
50
52
|
"husky": "^9.1.7",
|
|
51
|
-
"jest": "^
|
|
53
|
+
"jest": "^30.0.0",
|
|
52
54
|
"jison": "^0.4.18",
|
|
53
55
|
"onchange": "^7.1.0"
|
|
54
56
|
},
|