tldr-lint 0.0.21 → 0.0.23

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 CHANGED
@@ -71,10 +71,10 @@ TLDR009 | Page should contain a newline at end of file
71
71
  TLDR010 | Only Unix-style line endings allowed
72
72
  TLDR011 | Page never contains more than a single empty line
73
73
  TLDR012 | Page should contain no tabs
74
- TLDR013 | Title should be alphanumeric with dashes, underscores or spaces
74
+ TLDR013 | Title should be alphanumeric with dashes, underscores, spaces or allowed characters
75
75
  TLDR014 | Page should contain no trailing whitespace
76
76
  TLDR015 | Example descriptions should start with a capital letter
77
- TLDR016 | Label for information link should be spelled exactly `More information: `
77
+ TLDR016 | Label for information link should be spelled exactly `More information:` (with a succeeding whitespace)
78
78
  TLDR017 | Information link should be surrounded with angle brackets
79
79
  TLDR018 | Page should only include a single information link
80
80
  TLDR019 | Page should only include a maximum of 8 examples
@@ -91,7 +91,8 @@ 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
+ TLDR112 | Terms `stdin`, `stdout`, `stderr`, `regex`, and `glob` (including longer forms like "standard input", "regular expression", "glob pattern") should be lowercase and wrapped in backticks
95
+ TLDR113 | Translated line must not be identical to English line (only lines starting with `>` and `-` are checked)
95
96
 
96
97
  [npm-url]: https://www.npmjs.com/package/tldr-lint
97
98
  [npm-image]: https://img.shields.io/npm/v/tldr-lint.svg
package/lib/tldr-lint.js CHANGED
@@ -4,6 +4,8 @@ const parser = require('./tldr-parser.js').parser;
4
4
  const util = require('util');
5
5
 
6
6
  const MAX_EXAMPLES = 8;
7
+ const MIN_WORDS_PER_LINE = 2;
8
+ const ALLOWED_LOWERCASE_WORDS = ['macOS'];
7
9
 
8
10
  module.exports.ERRORS = parser.ERRORS = {
9
11
  'TLDR001': 'File should contain no leading whitespace',
@@ -28,7 +30,6 @@ module.exports.ERRORS = parser.ERRORS = {
28
30
  'TLDR020': 'Label for additional notes should be spelled exactly `Note: `',
29
31
  'TLDR021': 'Command example should not begin or end in whitespace',
30
32
 
31
-
32
33
  'TLDR101': 'Command description probably not properly annotated',
33
34
  'TLDR102': 'Example description probably not properly annotated',
34
35
  'TLDR103': 'Command example is missing its closing backtick',
@@ -40,7 +41,8 @@ module.exports.ERRORS = parser.ERRORS = {
40
41
  'TLDR109': 'File name should be lowercase',
41
42
  'TLDR110': 'Command example should not be empty',
42
43
  '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'
44
+ 'TLDR112': 'Terms `stdin`, `stdout`, `stderr`, `regex`, and `glob` should be lowercase and wrapped in backticks',
45
+ 'TLDR113': 'Translated line must not be identical to English line'
44
46
  };
45
47
 
46
48
  (function(parser) {
@@ -217,6 +219,38 @@ linter.processFile = function(file, verbose, alsoFormat, ignoreErrors) {
217
219
  result.errors.push({ locinfo: { first_line: '0' }, code: 'TLDR111', description: this.ERRORS.TLDR111 });
218
220
  }
219
221
 
222
+ const parts = file.split(path.sep);
223
+ const pagesIdx = parts.findIndex(seg => seg && seg.indexOf('pages.') === 0 && seg.length > 6);
224
+ if (pagesIdx !== -1 && parts[pagesIdx].slice(6) !== 'en') {
225
+ const englishParts = parts.slice();
226
+ englishParts[pagesIdx] = 'pages';
227
+ const englishPath = englishParts.join(path.sep);
228
+ if (fs.existsSync(englishPath)) {
229
+ const englishLines = fs.readFileSync(englishPath, 'utf8').split(/\r?\n/).map(l => l.trim());
230
+ const englishSet = new Set(englishLines);
231
+ const translatedLines = fs.readFileSync(file, 'utf8').split(/\r?\n/).map(l => l.trim());
232
+ translatedLines.forEach(function(line, idx) {
233
+ if (!line.match(/^[>-]/)) return;
234
+ if (!englishSet.has(line)) return;
235
+
236
+ const content = line.replace(/^[>-]\s/, '').trim();
237
+ const words = content.split(/\s/).filter(w => w.length > 0);
238
+ if (!(words.length > MIN_WORDS_PER_LINE)) return;
239
+
240
+ const everyWordCapitalized = words.length > 0 && words.every(word => {
241
+ const stripped = word.replace(/[()]/g, '');
242
+ if (!/[a-zA-Z]/.test(stripped)) return true;
243
+ if (ALLOWED_LOWERCASE_WORDS.includes(stripped.replace(/\W+$/, ''))) return true;
244
+
245
+ return /^[A-Z]/.test(stripped);
246
+ });
247
+ if (!everyWordCapitalized) {
248
+ result.errors.push({ locinfo: { first_line: (idx+1).toString() }, code: 'TLDR113', description: this.ERRORS.TLDR113 });
249
+ }
250
+ }, this);
251
+ }
252
+ }
253
+
220
254
  if (ignoreErrors) {
221
255
  ignoreErrors = ignoreErrors.split(',').map(function(val) {
222
256
  return val.trim();
@@ -707,7 +707,7 @@ case 7:
707
707
  if (this.topState() === "title") {
708
708
  yy_.yytext = this.matches[1];
709
709
  if (
710
- /[^\w+\[\]{}!%,^~$:><|?. -]/.test(yy_.yytext) ||
710
+ /[^\w+\[\]{}\(\)!%,^~$:><|?. -]/.test(yy_.yytext) ||
711
711
  (yy_.yytext.endsWith('.') && yy_.yytext !== '.' && yy_.yytext !== ' .')
712
712
  ) {
713
713
  yy.error(yy_.yylloc, 'TLDR013');
@@ -751,7 +751,7 @@ case 8:
751
751
  console.warn(`Description ends in \'${punctuation}\'. Consider writing your sentence on one line.`);
752
752
  }
753
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);
754
+ var termMatch = yy_.yytext.match(/(?:^|[^`-\w])(stdout|stdin|stderr|regex|regular\s+expression|standard\s+(?:in|input|out|output|err|error)|glob(?:\s+pattern)?)(?=[^`\w]|$)/i);
755
755
  if (termMatch) {
756
756
  // Skip if the term is inside angle brackets (URL)
757
757
  var beforeTerm = yy_.yytext.substring(0, termMatch.index + termMatch[0].indexOf(termMatch[1]));
@@ -765,6 +765,7 @@ case 8:
765
765
  else if (foundTerm.match(/^standard (in|input)$/)) term = 'stdin';
766
766
  else if (foundTerm.match(/^standard (out|output)$/)) term = 'stdout';
767
767
  else if (foundTerm.match(/^standard (err|error)$/)) term = 'stderr';
768
+ else if (foundTerm === 'glob pattern') term = 'glob';
768
769
  yy.errors.push({
769
770
  locinfo: yy_.yylloc,
770
771
  code: 'TLDR112',
@@ -796,7 +797,7 @@ case 9:
796
797
  yy.error(yy_.yylloc, 'TLDR104');
797
798
  }
798
799
  // 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
+ var termMatch = yy_.yytext.match(/(?:^|[^`-\w])(stdout|stdin|stderr|regex|regular\s+expression|standard\s+(?:in|input|out|output|err|error)|glob(?:\s+pattern)?)(?=[^`\w]|$)/i);
800
801
  if (termMatch) {
801
802
  // Skip if the term is inside angle brackets (URL)
802
803
  var beforeTerm = yy_.yytext.substring(0, termMatch.index + termMatch[0].indexOf(termMatch[1]));
@@ -810,6 +811,7 @@ case 9:
810
811
  else if (foundTerm.match(/^standard (in|input)$/)) term = 'stdin';
811
812
  else if (foundTerm.match(/^standard (out|output)$/)) term = 'stdout';
812
813
  else if (foundTerm.match(/^standard (err|error)$/)) term = 'stderr';
814
+ else if (foundTerm === 'glob pattern') term = 'glob';
813
815
  yy.errors.push({
814
816
  locinfo: yy_.yylloc,
815
817
  code: 'TLDR112',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tldr-lint",
3
- "version": "0.0.21",
3
+ "version": "0.0.23",
4
4
  "description": "A linting tool to validate tldr pages",
5
5
  "repository": {
6
6
  "type": "git",
@@ -42,12 +42,12 @@
42
42
  },
43
43
  "license": "MIT",
44
44
  "dependencies": {
45
- "commander": "^14.0.0"
45
+ "commander": "^15.0.0"
46
46
  },
47
47
  "devDependencies": {
48
- "concurrently": "^9.1.2",
49
- "eslint": "^9.17.0",
50
- "eslint-config-eslint": "^13.0.0",
48
+ "concurrently": "^10.0.1",
49
+ "eslint": "^10.1.0",
50
+ "eslint-config-eslint": "^14.0.0",
51
51
  "eslint-plugin-jest": "^29.0.1",
52
52
  "husky": "^9.1.7",
53
53
  "jest": "^30.0.0",