Skip to content

Commit

Permalink
feat: text-escaping rule; fixes #864
Browse files Browse the repository at this point in the history
  • Loading branch information
brettz9 committed Nov 1, 2022
1 parent da1c85f commit 1776e18
Show file tree
Hide file tree
Showing 8 changed files with 685 additions and 4 deletions.
1 change: 1 addition & 0 deletions .README/README.md
Expand Up @@ -587,4 +587,5 @@ selector).
{"gitdown": "include", "file": "./rules/require-yields-check.md"}
{"gitdown": "include", "file": "./rules/sort-tags.md"}
{"gitdown": "include", "file": "./rules/tag-lines.md"}
{"gitdown": "include", "file": "./rules/text-escaping.md"}
{"gitdown": "include", "file": "./rules/valid-types.md"}
30 changes: 30 additions & 0 deletions .README/rules/text-escaping.md
@@ -0,0 +1,30 @@
### `text-escaping`

This rule can auto-escape certain characters that are input within block and
tag descriptions.

This rule may be desirable if your text is known not to contain HTML or
Markdown and you therefore do not wish for it to be accidentally interpreted
as such by the likes of Visual Studio Code or if you wish to view it escaped
within it or your documentation.

#### Options

##### `escapeHTML`

This option escapes all `<` and `&` characters (except those followed by
whitespace which are treated as literals by Visual Studio Code).

##### `escapeMarkdown`

This option escapes the first backtick (`` ` ``) in a paired sequence.

|||
|---|---|
|Context|everywhere|
|Tags|``|
|Recommended|false|
|Settings||
|Options||

<!-- assertions textEscaping -->
154 changes: 152 additions & 2 deletions README.md
Expand Up @@ -72,6 +72,7 @@ JSDoc linting rules for ESLint.
* [`require-yields-check`](#user-content-eslint-plugin-jsdoc-rules-require-yields-check)
* [`sort-tags`](#user-content-eslint-plugin-jsdoc-rules-sort-tags)
* [`tag-lines`](#user-content-eslint-plugin-jsdoc-rules-tag-lines)
* [`text-escaping`](#user-content-eslint-plugin-jsdoc-rules-text-escaping)
* [`valid-types`](#user-content-eslint-plugin-jsdoc-rules-valid-types)


Expand Down Expand Up @@ -22100,6 +22101,155 @@ The following patterns are not considered problems:
````


<a name="user-content-eslint-plugin-jsdoc-rules-text-escaping"></a>
<a name="eslint-plugin-jsdoc-rules-text-escaping"></a>
### <code>text-escaping</code>

This rule can auto-escape certain characters that are input within block and
tag descriptions.

This rule may be desirable if your text is known not to contain HTML or
Markdown and you therefore do not wish for it to be accidentally interpreted
as such by the likes of Visual Studio Code or if you wish to view it escaped
within it or your documentation.

<a name="user-content-eslint-plugin-jsdoc-rules-text-escaping-options-42"></a>
<a name="eslint-plugin-jsdoc-rules-text-escaping-options-42"></a>
#### Options

<a name="user-content-eslint-plugin-jsdoc-rules-text-escaping-options-42-escapehtml"></a>
<a name="eslint-plugin-jsdoc-rules-text-escaping-options-42-escapehtml"></a>
##### <code>escapeHTML</code>

This option escapes all `<` and `&` characters (except those followed by
whitespace which are treated as literals by Visual Studio Code).

<a name="user-content-eslint-plugin-jsdoc-rules-text-escaping-options-42-escapemarkdown"></a>
<a name="eslint-plugin-jsdoc-rules-text-escaping-options-42-escapemarkdown"></a>
##### <code>escapeMarkdown</code>

This option escapes the first backtick (`` ` ``) in a paired sequence.

|||
|---|---|
|Context|everywhere|
|Tags|``|
|Recommended|false|
|Settings||
|Options||

The following patterns are considered problems:

````js
/**
* Some things to escape: <a> and &gt; and `test`
*/
// Message: You must include either `escapeHTML` or `escapeMarkdown`

/**
* Some things to escape: <a> and &gt; and &#xabc; and `test`
*/
// "jsdoc/text-escaping": ["error"|"warn", {"escapeHTML":true}]
// Message: You have unescaped HTML characters < or &

/**
* Some things to escape: <a> and &gt; and `test`
*/
// "jsdoc/text-escaping": ["error"|"warn", {"escapeMarkdown":true}]
// Message: You have unescaped Markdown backtick sequences

/**
* Some things to escape:
* <a> and &gt; and `test`
*/
// "jsdoc/text-escaping": ["error"|"warn", {"escapeHTML":true}]
// Message: You have unescaped HTML characters < or &

/**
* Some things to escape:
* <a> and &gt; and `test`
*/
// "jsdoc/text-escaping": ["error"|"warn", {"escapeMarkdown":true}]
// Message: You have unescaped Markdown backtick sequences

/**
* @param {SomeType} aName Some things to escape: <a> and &gt; and `test`
*/
// "jsdoc/text-escaping": ["error"|"warn", {"escapeHTML":true}]
// Message: You have unescaped HTML characters < or & in a tag

/**
* @param {SomeType} aName Some things to escape: <a> and &gt; and `test`
*/
// "jsdoc/text-escaping": ["error"|"warn", {"escapeMarkdown":true}]
// Message: You have unescaped Markdown backtick sequences in a tag

/**
* @param {SomeType} aName Some things to escape:
* <a> and &gt; and `test`
*/
// "jsdoc/text-escaping": ["error"|"warn", {"escapeHTML":true}]
// Message: You have unescaped HTML characters < or & in a tag

/**
* @param {SomeType} aName Some things to escape:
* <a> and &gt; and `test`
*/
// "jsdoc/text-escaping": ["error"|"warn", {"escapeMarkdown":true}]
// Message: You have unescaped Markdown backtick sequences in a tag
````

The following patterns are not considered problems:

````js
/**
* Some things to escape: &lt;a> and &gt; and `test`
*/
// "jsdoc/text-escaping": ["error"|"warn", {"escapeHTML":true}]

/**
* Some things to escape: <a> and &gt; and \`test`
*/
// "jsdoc/text-escaping": ["error"|"warn", {"escapeMarkdown":true}]

/**
* Some things to escape: < and &
*/
// "jsdoc/text-escaping": ["error"|"warn", {"escapeHTML":true}]

/**
* Some things to escape: `
*/
// "jsdoc/text-escaping": ["error"|"warn", {"escapeMarkdown":true}]

/**
* @param {SomeType} aName Some things to escape: &lt;a> and &gt; and `test`
*/
// "jsdoc/text-escaping": ["error"|"warn", {"escapeHTML":true}]

/**
* @param {SomeType} aName Some things to escape: <a> and &gt; and \`test`
*/
// "jsdoc/text-escaping": ["error"|"warn", {"escapeMarkdown":true}]

/**
* @param {SomeType} aName Some things to escape: < and &
*/
// "jsdoc/text-escaping": ["error"|"warn", {"escapeHTML":true}]

/**
* @param {SomeType} aName Some things to escape: `
*/
// "jsdoc/text-escaping": ["error"|"warn", {"escapeMarkdown":true}]

/**
* Nothing
* to escape
*/
// "jsdoc/text-escaping": ["error"|"warn", {"escapeHTML":true}]
````


<a name="user-content-eslint-plugin-jsdoc-rules-valid-types"></a>
<a name="eslint-plugin-jsdoc-rules-valid-types"></a>
### <code>valid-types</code>
Expand Down Expand Up @@ -22181,8 +22331,8 @@ for valid types (based on the tag's `type` value), and either portion checked
for presence (based on `false` `name` or `type` values or their `required`
value). See the setting for more details.

<a name="user-content-eslint-plugin-jsdoc-rules-valid-types-options-42"></a>
<a name="eslint-plugin-jsdoc-rules-valid-types-options-42"></a>
<a name="user-content-eslint-plugin-jsdoc-rules-valid-types-options-43"></a>
<a name="eslint-plugin-jsdoc-rules-valid-types-options-43"></a>
#### Options

- `allowEmptyNamepaths` (default: true) - Set to `false` to bulk disallow
Expand Down
3 changes: 3 additions & 0 deletions src/index.js
Expand Up @@ -46,6 +46,7 @@ import requireYields from './rules/requireYields';
import requireYieldsCheck from './rules/requireYieldsCheck';
import sortTags from './rules/sortTags';
import tagLines from './rules/tagLines';
import textEscaping from './rules/textEscaping';
import validTypes from './rules/validTypes';

export default {
Expand Down Expand Up @@ -103,6 +104,7 @@ export default {
'jsdoc/require-yields-check': 'warn',
'jsdoc/sort-tags': 'off',
'jsdoc/tag-lines': 'warn',
'jsdoc/text-escaping': 'off',
'jsdoc/valid-types': 'warn',
},
},
Expand Down Expand Up @@ -156,6 +158,7 @@ export default {
'require-yields-check': requireYieldsCheck,
'sort-tags': sortTags,
'tag-lines': tagLines,
'text-escaping': textEscaping,
'valid-types': validTypes,
},
};
50 changes: 48 additions & 2 deletions src/iterateJsdoc.js
Expand Up @@ -144,7 +144,7 @@ const getUtils = (
return jsdocUtils.getRegexFromString(str, requiredFlags);
};

utils.getTagDescription = (tg) => {
utils.getTagDescription = (tg, returnArray) => {
const descriptions = [];
tg.source.some(({
tokens: {
Expand Down Expand Up @@ -179,7 +179,26 @@ const getUtils = (
return false;
});

return descriptions.join('\n');
return returnArray ? descriptions : descriptions.join('\n');
};

utils.setTagDescription = (tg, matcher, setter) => {
let finalIdx = 0;
tg.source.some(({
tokens: {
description,
},
}, idx) => {
if (description && matcher.test(description)) {
tg.source[idx].tokens.description = setter(description);
finalIdx = idx;
return true;
}

return false;
});

return finalIdx;
};

utils.getDescription = () => {
Expand Down Expand Up @@ -207,10 +226,37 @@ const getUtils = (

return {
description: descriptions.join('\n'),
descriptions,
lastDescriptionLine,
};
};

utils.setDescriptionLines = (matcher, setter) => {
let finalIdx = 0;
jsdoc.source.some(({
tokens: {
description,
tag,
end,
},
}, idx) => {
// istanbul ignore if -- Already checked
if (idx && (tag || end)) {
return true;
}

if (description && matcher.test(description)) {
jsdoc.source[idx].tokens.description = setter(description);
finalIdx = idx;
return true;
}

return false;
});

return finalIdx;
};

utils.changeTag = (tag, ...tokens) => {
for (const [
idx,
Expand Down

0 comments on commit 1776e18

Please sign in to comment.