Skip to content

Commit 5022ea4

Browse files
committed
fix: Ensure notation for config that warns/disables a rule does not wrap to separate line (attempt 2)
1 parent 8353b38 commit 5022ea4

File tree

5 files changed

+94
-92
lines changed

5 files changed

+94
-92
lines changed

README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -219,11 +219,11 @@ If you have a build step for your code like [Babel](https://babeljs.io/) or [Typ
219219

220220
### markdownlint
221221

222-
The output of this tool should be compatible with [markdownlint](https://github.com/DavidAnson/markdownlint) which you might use to lint your markdown. However, if any of your ESLint configs disable your rules or set them to warn, you'll need to exempt some elements used for the emoji superscript from [no-inline-html](https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md#md033---inline-html):
222+
The output of this tool should be compatible with [markdownlint](https://github.com/DavidAnson/markdownlint) which you might use to lint your markdown. However, if any of your ESLint configs disable your rules or set them to warn, you'll need to exempt some elements used for emoji superscripts from [no-inline-html](https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md#md033---inline-html):
223223

224224
```json
225225
{
226-
"no-inline-html": { "allowed_elements": ["span", "sup"] }
226+
"no-inline-html": { "allowed_elements": ["br", "sup"] }
227227
}
228228
```
229229

lib/configs.ts

+4-13
Original file line numberDiff line numberDiff line change
@@ -98,19 +98,12 @@ export function parseConfigEmojiOptions(
9898
return configEmojis;
9999
}
100100

101-
function emojiWithSuperscript(
102-
emoji: string,
103-
superscriptEmoji: string,
104-
noWrap = false
105-
) {
101+
function emojiWithSuperscript(emoji: string, superscriptEmoji: string) {
106102
if (emoji === superscriptEmoji) {
107103
// Avoid double emoji.
108104
return emoji;
109105
}
110-
// Style is to ensure superscript doesn't wrap to separate line, useful in constrained spaces.
111-
return noWrap
112-
? `<span style="white-space:nowrap">${emoji}<sup>${superscriptEmoji}</sup></span>`
113-
: `${emoji}<sup>${superscriptEmoji}</sup>`;
106+
return `${emoji}<sup>${superscriptEmoji}</sup>`;
114107
}
115108

116109
/**
@@ -120,7 +113,6 @@ function emojiWithSuperscript(
120113
* @param options
121114
* @param options.severity - if present, decorate the config's emoji for the given severity level
122115
* @param options.fallback - if true and no emoji is found, choose whether to fallback to a generic config emoji or a badge
123-
* @param options.noWrap - whether to add styling to ensure the superscript doesn't wrap to a separate line when used in constrained spaces
124116
* @returns the string to display for the config
125117
*/
126118
export function findConfigEmoji(
@@ -129,7 +121,6 @@ export function findConfigEmoji(
129121
options?: {
130122
severity?: SEVERITY_TYPE;
131123
fallback?: 'badge' | 'emoji';
132-
noWrap?: boolean;
133124
}
134125
) {
135126
let emoji = configEmojis.find(
@@ -148,9 +139,9 @@ export function findConfigEmoji(
148139

149140
switch (options?.severity) {
150141
case 'warn':
151-
return emojiWithSuperscript(emoji, EMOJI_CONFIG_WARN, options.noWrap);
142+
return emojiWithSuperscript(emoji, EMOJI_CONFIG_WARN);
152143
case 'off':
153-
return emojiWithSuperscript(emoji, EMOJI_CONFIG_OFF, options.noWrap);
144+
return emojiWithSuperscript(emoji, EMOJI_CONFIG_OFF);
154145
default:
155146
return emoji;
156147
}

lib/rule-list.ts

+64-61
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,7 @@ import { findSectionHeader } from './markdown.js';
1111
import { getPluginRoot } from './package-json.js';
1212
import { generateLegend } from './legend.js';
1313
import { relative } from 'node:path';
14-
import {
15-
COLUMN_TYPE,
16-
SEVERITY_ERROR,
17-
SEVERITY_WARN,
18-
SEVERITY_OFF,
19-
SEVERITY_TYPE,
20-
} from './types.js';
14+
import { COLUMN_TYPE, SEVERITY_TYPE, SEVERITY_TYPE_TO_SET } from './types.js';
2115
import { markdownTable } from 'markdown-table';
2216
import camelCase from 'camelcase';
2317
import type {
@@ -65,78 +59,87 @@ function getPropertyFromRule(
6559
return result;
6660
}
6761

62+
/**
63+
* Get the emojis for the configs that set a rule to a certain severity.
64+
*/
65+
function getEmojisForConfigsSettingRuleToSeverity(
66+
ruleName: string,
67+
configsToRulesWithoutIgnored: ConfigsToRules,
68+
pluginPrefix: string,
69+
configEmojis: ConfigEmojis,
70+
severityType: SEVERITY_TYPE
71+
) {
72+
const severity = SEVERITY_TYPE_TO_SET[severityType];
73+
const configsOfThisSeverity = getConfigsForRule(
74+
ruleName,
75+
configsToRulesWithoutIgnored,
76+
pluginPrefix,
77+
severity
78+
);
79+
80+
const emojis: string[] = [];
81+
for (const configName of configsOfThisSeverity) {
82+
// Find the emoji for each config or otherwise use a badge that can be defined in markdown.
83+
const emoji = findConfigEmoji(configEmojis, configName, {
84+
severity: severityType,
85+
fallback: 'badge',
86+
});
87+
/* istanbul ignore next -- this shouldn't happen */
88+
if (typeof emoji !== 'string') {
89+
throw new TypeError('Emoji will always be a string thanks to fallback');
90+
}
91+
// For emojis with a superscript, add a newline first to ensure we don't end up with a linebreak between the emoji and the superscript.
92+
emojis.push(emoji.includes('<sup>') ? `<br>${emoji}` : emoji);
93+
}
94+
95+
return emojis;
96+
}
97+
6898
function getConfigurationColumnValueForRule(
6999
rule: RuleDetails,
70100
configsToRules: ConfigsToRules,
71101
pluginPrefix: string,
72102
configEmojis: ConfigEmojis,
73103
ignoreConfig: string[]
74104
): string {
75-
const badges: string[] = [];
105+
const emojis: string[] = [];
76106

77107
const configsToRulesWithoutIgnored = Object.fromEntries(
78108
Object.entries(configsToRules).filter(
79109
([configName]) => !ignoreConfig?.includes(configName)
80110
)
81111
);
82112

83-
const configsEnabled = getConfigsForRule(
84-
rule.name,
85-
configsToRulesWithoutIgnored,
86-
pluginPrefix,
87-
SEVERITY_ERROR
88-
);
89-
90-
const configsWarn = getConfigsForRule(
91-
rule.name,
92-
configsToRulesWithoutIgnored,
93-
pluginPrefix,
94-
SEVERITY_WARN
95-
);
96-
97-
const configsOff = getConfigsForRule(
98-
rule.name,
99-
configsToRulesWithoutIgnored,
100-
pluginPrefix,
101-
SEVERITY_OFF
113+
// Collect the emojis for the configs that set the rule to each severity level.
114+
emojis.push(
115+
...getEmojisForConfigsSettingRuleToSeverity(
116+
rule.name,
117+
configsToRulesWithoutIgnored,
118+
pluginPrefix,
119+
configEmojis,
120+
SEVERITY_TYPE.error
121+
),
122+
...getEmojisForConfigsSettingRuleToSeverity(
123+
rule.name,
124+
configsToRulesWithoutIgnored,
125+
pluginPrefix,
126+
configEmojis,
127+
SEVERITY_TYPE.warn
128+
),
129+
...getEmojisForConfigsSettingRuleToSeverity(
130+
rule.name,
131+
configsToRulesWithoutIgnored,
132+
pluginPrefix,
133+
configEmojis,
134+
SEVERITY_TYPE.off
135+
)
102136
);
103137

104-
// Find the emoji for each config or otherwise use a badge that can be defined in markdown.
105-
106-
for (const configName of configsEnabled) {
107-
badges.push(
108-
// @ts-expect-error -- will always be a string thanks to fallback
109-
findConfigEmoji(configEmojis, configName, {
110-
severity: SEVERITY_TYPE.error,
111-
fallback: 'badge',
112-
noWrap: true,
113-
})
114-
);
115-
}
116-
117-
for (const configName of configsWarn) {
118-
badges.push(
119-
// @ts-expect-error -- will always be a string thanks to fallback
120-
findConfigEmoji(configEmojis, configName, {
121-
severity: SEVERITY_TYPE.warn,
122-
fallback: 'badge',
123-
noWrap: true,
124-
})
125-
);
126-
}
127-
128-
for (const configName of configsOff) {
129-
badges.push(
130-
// @ts-expect-error -- will always be a string thanks to fallback
131-
findConfigEmoji(configEmojis, configName, {
132-
severity: SEVERITY_TYPE.off,
133-
fallback: 'badge',
134-
noWrap: true,
135-
})
136-
);
138+
if (emojis.length > 0 && emojis[0].startsWith('<br>')) {
139+
emojis[0] = emojis[0].slice(4); // Avoid any leading linebreak. Linebreak only necessary after emojis and before emojis with superscripts.
137140
}
138141

139-
return badges.join(' ');
142+
return emojis.join(' ');
140143
}
141144

142145
function buildRuleRow(

lib/types.ts

+8
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,14 @@ export enum SEVERITY_TYPE {
2424
'off' = 'off',
2525
}
2626

27+
export const SEVERITY_TYPE_TO_SET: {
28+
[key in SEVERITY_TYPE]: Set<TSESLint.Linter.RuleLevel>;
29+
} = {
30+
[SEVERITY_TYPE.error]: SEVERITY_ERROR,
31+
[SEVERITY_TYPE.warn]: SEVERITY_WARN,
32+
[SEVERITY_TYPE.off]: SEVERITY_OFF,
33+
};
34+
2735
export type ConfigsToRules = Record<string, Rules>;
2836

2937
export interface RuleDetails {

test/lib/__snapshots__/generator-test.ts.snap

+16-16
Original file line numberDiff line numberDiff line change
@@ -615,15 +615,15 @@ exports[`generator #generate rules that are disabled or set to warn generates th
615615
✅<sup>⚠️</sup> Warns in the \`recommended\` configuration.\\
616616
✅<sup>🚫</sup> Disabled in the \`recommended\` configuration.
617617
618-
| Name | Description | 💼 |
619-
| :----------------------------- | :--------------------- | :--------------------------------------------------------------------------------------------------------------------- |
620-
| [no-bar](docs/rules/no-bar.md) | Description of no-bar. | <span style="white-space:nowrap">![other][]<sup>🚫</sup></span> <span style="white-space:nowrap">✅<sup>🚫</sup></span> |
621-
| [no-baz](docs/rules/no-baz.md) | Description of no-baz. | ✅ <span style="white-space:nowrap">![other][]<sup>🚫</sup></span> |
622-
| [no-bez](docs/rules/no-bez.md) | Description of no-bez. | <span style="white-space:nowrap">![other][]<sup>⚠️</sup></span> |
623-
| [no-biz](docs/rules/no-biz.md) | Description of no-biz. | <span style="white-space:nowrap">![other][]<sup>🚫</sup></span> |
624-
| [no-boz](docs/rules/no-boz.md) | Description of no-boz. | <span style="white-space:nowrap">✅<sup>⚠️</sup></span> |
625-
| [no-buz](docs/rules/no-buz.md) | Description of no-buz. | <span style="white-space:nowrap">![other][]<sup>⚠️</sup></span> <span style="white-space:nowrap">✅<sup>⚠️</sup></span> |
626-
| [no-foo](docs/rules/no-foo.md) | Description of no-foo. | <span style="white-space:nowrap">✅<sup>🚫</sup></span> |
618+
| Name | Description | 💼 |
619+
| :----------------------------- | :--------------------- | :----------------------------------------- |
620+
| [no-bar](docs/rules/no-bar.md) | Description of no-bar. | ![other][]<sup>🚫</sup> <br>✅<sup>🚫</sup> |
621+
| [no-baz](docs/rules/no-baz.md) | Description of no-baz. | ✅ <br>![other][]<sup>🚫</sup> |
622+
| [no-bez](docs/rules/no-bez.md) | Description of no-bez. | ![other][]<sup>⚠️</sup> |
623+
| [no-biz](docs/rules/no-biz.md) | Description of no-biz. | ![other][]<sup>🚫</sup> |
624+
| [no-boz](docs/rules/no-boz.md) | Description of no-boz. | ✅<sup>⚠️</sup> |
625+
| [no-buz](docs/rules/no-buz.md) | Description of no-buz. | ![other][]<sup>⚠️</sup> <br>✅<sup>⚠️</sup> |
626+
| [no-foo](docs/rules/no-foo.md) | Description of no-foo. | ✅<sup>🚫</sup> |
627627
628628
<!-- end auto-generated rules list -->
629629
"
@@ -699,10 +699,10 @@ exports[`generator #generate rules that are disabled or set to warn, only one co
699699
✅<sup>⚠️</sup> Warns in the \`recommended\` configuration.\\
700700
✅<sup>🚫</sup> Disabled in the \`recommended\` configuration.
701701
702-
| Name | Description | ✅ |
703-
| :----------------------------- | :--------------------- | :----------------------------------------------------- |
704-
| [no-bar](docs/rules/no-bar.md) | Description of no-bar. | <span style="white-space:nowrap">✅<sup>🚫</sup></span> |
705-
| [no-foo](docs/rules/no-foo.md) | Description of no-foo. | <span style="white-space:nowrap">✅<sup>⚠️</sup></span> |
702+
| Name | Description | ✅ |
703+
| :----------------------------- | :--------------------- | :------------- |
704+
| [no-bar](docs/rules/no-bar.md) | Description of no-bar. | ✅<sup>🚫</sup> |
705+
| [no-foo](docs/rules/no-foo.md) | Description of no-foo. | ✅<sup>⚠️</sup> |
706706
707707
<!-- end auto-generated rules list -->
708708
"
@@ -734,9 +734,9 @@ exports[`generator #generate rules that are disabled or set to warn, two configs
734734
✅<sup>⚠️</sup> Warns in the \`recommended\` configuration.\\
735735
⌨️<sup>🚫</sup> Disabled in the \`typescript\` configuration.
736736
737-
| Name | Description | 💼 |
738-
| :----------------------------- | :--------------------- | :------------------------------------------------------------------------------------------------------------- |
739-
| [no-foo](docs/rules/no-foo.md) | Description of no-foo. | <span style="white-space:nowrap">✅<sup>⚠️</sup></span> <span style="white-space:nowrap">⌨️<sup>🚫</sup></span> |
737+
| Name | Description | 💼 |
738+
| :----------------------------- | :--------------------- | :--------------------------------- |
739+
| [no-foo](docs/rules/no-foo.md) | Description of no-foo. | ✅<sup>⚠️</sup> <br>⌨️<sup>🚫</sup> |
740740
741741
<!-- end auto-generated rules list -->
742742
"

0 commit comments

Comments
 (0)