Skip to content

Commit 57e2a54

Browse files
committed
fix(check-indentation): ignore example code blocks
This adds an `excludeExamples` option, defaulting to `true`. When enabled (or not configured) it will mask all `@example` tags and their content before testing indentation. That prevents errors about indentation inside example code blocks and keeps correct line numbers when reporting indentation error found elsewhere. It should fix gajus#334.
1 parent 3558377 commit 57e2a54

File tree

3 files changed

+93
-1
lines changed

3 files changed

+93
-1
lines changed

README.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -866,6 +866,20 @@ function quux () {
866866
*/
867867
class Moo {}
868868
// Message: There must be no indentation.
869+
870+
/**
871+
* foo
872+
*
873+
* @example
874+
* function xFoo () {
875+
* return 'foo';
876+
* }
877+
*/
878+
function quux () {
879+
880+
}
881+
// Options: ["excludeExamples":false}]
882+
// Message: There must be no indentation.
869883
````
870884

871885
The following patterns are not considered problems:
@@ -885,6 +899,19 @@ function quux () {
885899
function quux () {
886900

887901
}
902+
903+
/**
904+
* foo
905+
*
906+
* @example
907+
* function xFoo () {
908+
* return 'foo';
909+
* }
910+
*/
911+
function quux () {
912+
913+
}
914+
// Options: ["excludeExamples":true}]
888915
````
889916

890917

src/rules/checkIndentation.js

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,25 @@
11
import iterateJsdoc from '../iterateJsdoc';
22

3+
const maskExamples = (str) => {
4+
const regExamples = /([ \t]+\*)[ \t]@example(?=[ \n])([\w|\W]*?\n)(?=[ \t]*\*(?:[ \t]*@|\/))/g;
5+
return str.replace(regExamples, function hideCode (m, margin, code) {
6+
return (new Array(code.match(/\n/g).length + 1)).join(margin + '\n');
7+
});
8+
};
9+
310
export default iterateJsdoc(({
411
sourceCode,
512
jsdocNode,
613
report,
14+
context,
715
}) => {
16+
const options = context.options[0] || {};
17+
const {
18+
excludeExamples = true
19+
} = options;
20+
821
const reg = new RegExp(/^(?:\/?\**|[ \t]*)\*[ \t]{2}/gm);
9-
const text = sourceCode.getText(jsdocNode);
22+
const text = excludeExamples ? maskExamples(sourceCode.getText(jsdocNode)) : sourceCode.getText(jsdocNode);
1023

1124
if (reg.test(text)) {
1225
const lineBreaks = text.slice(0, reg.lastIndex).match(/\n/g) || [];
@@ -17,6 +30,16 @@ export default iterateJsdoc(({
1730
}, {
1831
iterateAllJsdocs: true,
1932
meta: {
33+
schema: [{
34+
additionalProperties: false,
35+
properties: {
36+
excludeExamples: {
37+
default: true,
38+
type: 'boolean'
39+
},
40+
},
41+
type: 'object'
42+
}],
2043
type: 'layout',
2144
},
2245
});

test/rules/assertions/checkIndentation.js

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,30 @@ export default {
4848
},
4949
],
5050
},
51+
{
52+
code: `
53+
/**
54+
* foo
55+
*
56+
* @example
57+
* function xFoo () {
58+
* return 'foo';
59+
* }
60+
*/
61+
function quux () {
62+
63+
}
64+
`,
65+
errors: [
66+
{
67+
line: 7,
68+
message: 'There must be no indentation.',
69+
},
70+
],
71+
options: [{
72+
excludeExamples: false,
73+
}],
74+
},
5175
],
5276
valid: [
5377
{
@@ -71,5 +95,23 @@ export default {
7195
}
7296
`,
7397
},
98+
{
99+
code: `
100+
/**
101+
* foo
102+
*
103+
* @example
104+
* function xFoo () {
105+
* return 'foo';
106+
* }
107+
*/
108+
function quux () {
109+
110+
}
111+
`,
112+
options: [{
113+
excludeExamples: true,
114+
}],
115+
},
74116
],
75117
};

0 commit comments

Comments
 (0)