Skip to content

Commit 6343a75

Browse files
Improve list item check regarding hyphen (#185)
Co-authored-by: Sindre Sorhus <[email protected]>
1 parent b0ce79d commit 6343a75

File tree

5 files changed

+65
-18
lines changed

5 files changed

+65
-18
lines changed

rules/list-item.js

Lines changed: 40 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -102,21 +102,49 @@ function validateList(list, file) {
102102
continue;
103103
}
104104

105-
const [link, ...description] = paragraph.children;
106-
107-
if (link.type === 'text') {
105+
if (paragraph.children[0].type === 'text') {
108106
continue;
109107
}
110108

109+
let [link, ...description] = paragraph.children;
110+
111+
// Might have children like: '{image} {text} {link} { - description}'
112+
// Keep discarding prefix elements until we find something link-like.
113+
while (link.type !== 'linkReference' && link.type !== 'link' && description.length > 1) {
114+
link = description[0];
115+
description = description.slice(1);
116+
}
117+
111118
if (!validateListItemLink(link, file)) {
112119
continue;
113120
}
114121

122+
if (!validateListItemLinkChildren(link, file)) {
123+
continue;
124+
}
125+
115126
validateListItemDescription(description, file);
116127
}
117128
}
118129

130+
function validateListItemLinkChildren(link, file) {
131+
for (const node of link.children) {
132+
if (!listItemLinkNodeAllowList.has(node.type)) {
133+
file.message('Invalid list item link', node);
134+
return false;
135+
}
136+
}
137+
138+
return true;
139+
}
140+
119141
function validateListItemLink(link, file) {
142+
// NB. We need remark-lint-no-undefined-references separately
143+
// to catch if this is a valid reference. Here we only care that it exists.
144+
if (link.type === 'linkReference') {
145+
return true;
146+
}
147+
120148
if (link.type !== 'link') {
121149
file.message('Invalid list item link', link);
122150
return false;
@@ -133,13 +161,6 @@ function validateListItemLink(link, file) {
133161
return false;
134162
}
135163

136-
for (const node of link.children) {
137-
if (!listItemLinkNodeAllowList.has(node.type)) {
138-
file.message('Invalid list item link', node);
139-
return false;
140-
}
141-
}
142-
143164
return true;
144165
}
145166

@@ -168,11 +189,18 @@ function validateListItemDescription(description, file) {
168189
return false;
169190
}
170191

171-
if (/^\s*/.test(prefixText)) {
172-
file.message('List item link and description separated by invalid en-dash', prefix);
192+
// Some editors auto-correct ' - ' to – (en-dash). Also avoid — (em-dash).
193+
if (/^\s*[/\u{02013}\u{02014}]/u.test(prefixText)) {
194+
file.message('List item link and description separated by invalid en-dash or em-dash', prefix);
173195
return false;
174196
}
175197

198+
// Might have image and link on left side before description.
199+
// Assume a hyphen with spaces in the description is good enough.
200+
if (/ - [A-Z]/.test(descriptionText)) {
201+
return true;
202+
}
203+
176204
file.message('List item link and description must be separated with a dash', prefix);
177205
return false;
178206
}

test/fixtures/list-item/0.md

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@ All list-items in this document should be linted as **valid**.
2424
- [foo](https://foo.com) - Valid sub-item.
2525
- [foo](https://foo.com) - Valid sub-item.
2626
- [foo](https://foo.com) - Valid sub-sub-item!!!!!
27-
- [foo](https://foo.com) - GitHub's descriptions can also be valid.
27+
- [foo](https://foo.com) - GitHub's descriptions can also be valid.
28+
- [foo-bar](https://foo-bar.com) - Valid description.
29+
- 👍 [foo](https://foo-bar.com) - Valid description.
2830

2931
## Tutorials
3032

@@ -133,9 +135,17 @@ These sub-lists use mixed indentation (spaces and tabs).
133135

134136
- [why-is-node-running](https://github.com/mafintosh/why-is-node-running) - Node.js is running but you don't know why?
135137

136-
<!--
137-
TODO: these list-items should possibly lint as valid, but they currently don't.
138138

139-
- ![v3](img/vapor-3.png) [API Error Middleware](https://github.com/skelpo/APIErrorMiddleware) – Vapor middleware for converting thrown errors to JSON responses.
140-
- ![v2](img/vapor-2.png) ![v3](img/vapor-3.png) [Bugsnag](https://github.com/nodes-vapor/bugsnag) – Report errors with Bugsnag.
139+
- [gtkada] - Ada graphical toolkit based on Gtk3 components (issue #161 link reference below but checked by `remark-lint-no-undefined-references` not `rules/list-item.js`).
140+
- [*example* `code`][exampleref] - Another linkref but with children.
141+
- [foo](https://foo.com) ![stars](https://img.shields.io/github/stars/foo/foo.svg) - Valid description.
142+
- ![v3](img/vapor-3.png) [API Error Middleware](https://github.com/skelpo/APIErrorMiddleware) - Vapor middleware for converting thrown errors to JSON responses.
143+
- ![v2](img/vapor-2.png) ![v3](img/vapor-3.png) [Bugsnag](https://github.com/nodes-vapor/bugsnag) - Report errors with Bugsnag.
144+
- [ArcGIS location services - Postman Workspace](https://www.postman.com/arcgis-developer/workspace/arcgis-location-services) - Official Postman collections to work with the Geocoding & Search API, Routing & Directions API, Demographics & GeoEnrichment API, Data hosting and more (issue #146).
145+
- [rmw](https://github.com/ros2/rmw/tree/master/rmw) - Contains the ROS middleware API ![rmw](https://img.shields.io/github/stars/ros2/rmw.svg) (issue #49).
146+
<!-- TODO
147+
- [__Compiling machine learning programs via high-level tracing__. Roy Frostig, Matthew James Johnson, Chris Leary. _MLSys 2018_.](https://mlsys.org/Conferences/doc/2018/146.pdf) - This white paper describes an early version of JAX, detailing how computation is traced and compiled (issue #136)
141148
-->
149+
150+
[gtkada]: https://github.com/AdaCore/gtkada
151+
[exampleref]: https://example.com

test/fixtures/list-item/1.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,3 +70,7 @@ Test description's ending punctuation.
7070

7171
- [foo](https://foo.com) - Quote-inducing double punctuation “end…”??!
7272
- [foo](https://foo.com) - Quote-inducing double punctuation “end?…...”…...?
73+
- [gtkada] - Reference link with no reference.
74+
- [*example* ![img](https://image.img)][exampleref] - Another linkref but with a bad child.
75+
76+
[exampleref]: https://ref.com

test/rules/snapshots/list-item.js.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ Generated by [AVA](https://avajs.dev).
4646
},
4747
{
4848
line: 13,
49-
message: 'List item link and description separated by invalid en-dash',
49+
message: 'List item link and description separated by invalid en-dash or em-dash',
5050
ruleId: 'awesome-list-item',
5151
},
5252
{
@@ -279,6 +279,11 @@ Generated by [AVA](https://avajs.dev).
279279
message: 'List item description must end with proper punctuation',
280280
ruleId: 'awesome-list-item',
281281
},
282+
{
283+
line: 74,
284+
message: 'Invalid list item link',
285+
ruleId: 'awesome-list-item',
286+
},
282287
]
283288

284289
## list-item - invalid sublist punctuation
40 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)