Repository: sindresorhus/awesome-lint (js)

Issue:
… (which is not ...) could be considered valid punctuation. 
I get a 

```
List item description must end with proper punctuation                          remark-lint:awesome-list-item
```
On a line that finishes with … (the utf-8 caracter, not three dots `...`). 

Pull request description:
Support `…` as punctuation in `list-item` rule
Closes #97

Patch:
diff --git a/.travis.yml b/.travis.yml
index f3fa8cd..9d7745e 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,4 +1,5 @@
 language: node_js
 node_js:
+  - '14'
+  - '12'
   - '10'
-  - '8'
diff --git a/config.js b/config.js
index 81d6872..cc2e3b1 100644
--- a/config.js
+++ b/config.js
@@ -52,7 +52,7 @@ exports.plugins = [
 	// Third-party plugins
 	// Disabled as it throws `file.warn is not a function`
 	// require('remark-lint-no-empty-sections'),
-	require('remark-lint-no-dead-urls'),
+
 	require('remark-lint-match-punctuation'),
 	require('remark-lint-no-repeat-punctuation'),
 
diff --git a/index.js b/index.js
index 87a1373..c513b7c 100644
--- a/index.js
+++ b/index.js
@@ -60,19 +60,19 @@ lint.report = async options => {
 };
 
 lint._report = async (options, spinner) => {
-	let temp = null;
+	let temporary = null;
 
 	if (isUrl(options.filename)) {
 		if (!isGithubUrl(options.filename, {repository: true})) {
 			throw new Error(`Invalid GitHub repo URL: ${options.filename}`);
 		}
 
-		temp = tempy.directory();
-		await pify(gitClone)(options.filename, temp);
+		temporary = tempy.directory();
+		await pify(gitClone)(options.filename, temporary);
 
-		const readme = findReadmeFile(temp);
+		const readme = findReadmeFile(temporary);
 		if (!readme) {
-			await rmfr(temp);
+			await rmfr(temporary);
 			throw new Error(`Unable to find valid readme for "${options.filename}"`);
 		}
 
@@ -87,8 +87,8 @@ lint._report = async (options, spinner) => {
 		messages.push(...vfile.messages);
 	}
 
-	if (temp) {
-		await rmfr(temp);
+	if (temporary) {
+		await rmfr(temporary);
 	}
 
 	if (messages.length === 0) {
diff --git a/lib/spell-check-rules.js b/lib/spell-check-rules.js
index 6042de5..f85cf57 100644
--- a/lib/spell-check-rules.js
+++ b/lib/spell-check-rules.js
@@ -6,7 +6,7 @@ module.exports = [
 		value: 'Node.js'
 	},
 	{
-		test: /\bStack\s?Overflow\b/gi,
+		test: /\bstack\s?overflow\b/gi,
 		value: 'Stack Overflow'
 	},
 	{
@@ -14,15 +14,15 @@ module.exports = [
 		value: 'JavaScript'
 	},
 	{
-		test: [/\bmac\s?OS(?!\s?X)\b/gi, /(mac\s?)?OS\s?X/gi],
+		test: [/\bmac\s?os(?!\s?x)\b/gi, /(mac\s?)?os\s?x/gi],
 		value: 'macOS'
 	},
 	{
-		test: /\bYou\s?Tube\b/gi,
+		test: /\byou\s?tube\b/gi,
 		value: 'YouTube'
 	},
 	{
-		test: /\bGit\s?Hub\b/gi,
+		test: /\bgit\s?hub\b/gi,
 		value: 'GitHub'
 	}
 ];
diff --git a/license b/license
index e7af2f7..fa7ceba 100644
--- a/license
+++ b/license
@@ -1,6 +1,6 @@
 MIT License
 
-Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
+Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com)
 
 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
 
diff --git a/package.json b/package.json
index dea15c8..0297e07 100644
--- a/package.json
+++ b/package.json
@@ -1,17 +1,18 @@
 {
 	"name": "awesome-lint",
-	"version": "0.12.1",
+	"version": "0.13.0",
 	"description": "Linter for Awesome lists",
 	"license": "MIT",
 	"repository": "sindresorhus/awesome-lint",
+	"funding": "https://github.com/sponsors/sindresorhus",
 	"author": {
 		"name": "Sindre Sorhus",
 		"email": "sindresorhus@gmail.com",
-		"url": "sindresorhus.com"
+		"url": "https://sindresorhus.com"
 	},
 	"bin": "cli.js",
 	"engines": {
-		"node": ">=8"
+		"node": ">=10"
 	},
 	"scripts": {
 		"test": "xo && ava"
@@ -37,7 +38,7 @@
 	"dependencies": {
 		"arrify": "^2.0.1",
 		"case": "^1.5.5",
-		"emoji-regex": "^8.0.0",
+		"emoji-regex": "^9.0.0",
 		"execa": "^1.0.0",
 		"git-clone": "^0.1.0",
 		"github-slugger": "^1.2.0",
@@ -47,74 +48,73 @@
 		"is-github-url": "^1.2.2",
 		"is-url-superb": "^3.0.0",
 		"mdast-util-to-string": "^1.0.4",
-		"meow": "^5.0.0",
-		"ora": "^3.0.0",
+		"meow": "^7.0.1",
+		"ora": "^4.0.4",
 		"parse-github-url": "^1.0.2",
-		"pify": "^4.0.0",
+		"pify": "^5.0.0",
 		"read-pkg": "^5.1.1",
-		"remark": "^11.0.2",
-		"remark-lint": "^6.0.2",
-		"remark-lint-blockquote-indentation": "^1.0.2",
-		"remark-lint-checkbox-character-style": "^1.0.2",
-		"remark-lint-checkbox-content-indent": "^1.0.2",
-		"remark-lint-code-block-style": "^1.0.2",
-		"remark-lint-definition-case": "^1.0.2",
-		"remark-lint-definition-spacing": "^1.0.2",
-		"remark-lint-emphasis-marker": "^1.0.2",
-		"remark-lint-fenced-code-marker": "^1.0.2",
+		"remark": "^12.0.0",
+		"remark-lint": "^7.0.0",
+		"remark-lint-blockquote-indentation": "^2.0.0",
+		"remark-lint-checkbox-character-style": "^2.0.0",
+		"remark-lint-checkbox-content-indent": "^2.0.0",
+		"remark-lint-code-block-style": "^2.0.0",
+		"remark-lint-definition-case": "^2.0.0",
+		"remark-lint-definition-spacing": "^2.0.0",
+		"remark-lint-emphasis-marker": "^2.0.0",
+		"remark-lint-fenced-code-marker": "^2.0.0",
 		"remark-lint-file-extension": "^1.0.2",
 		"remark-lint-final-newline": "^1.0.2",
-		"remark-lint-hard-break-spaces": "^1.0.3",
-		"remark-lint-heading-style": "^1.0.2",
-		"remark-lint-link-title-style": "^1.0.2",
-		"remark-lint-list-item-bullet-indent": "^1.0.2",
-		"remark-lint-list-item-content-indent": "^1.0.2",
-		"remark-lint-list-item-indent": "^1.0.2",
+		"remark-lint-hard-break-spaces": "^2.0.0",
+		"remark-lint-heading-style": "^2.0.0",
+		"remark-lint-link-title-style": "^2.0.0",
+		"remark-lint-list-item-bullet-indent": "^2.0.0",
+		"remark-lint-list-item-content-indent": "^2.0.0",
+		"remark-lint-list-item-indent": "^2.0.0",
 		"remark-lint-match-punctuation": "^0.2.0",
-		"remark-lint-no-auto-link-without-protocol": "^1.0.2",
-		"remark-lint-no-blockquote-without-marker": "^2.0.2",
-		"remark-lint-no-dead-urls": "^1.0.0",
-		"remark-lint-no-emphasis-as-heading": "^1.0.2",
-		"remark-lint-no-empty-sections": "^3.0.0",
+		"remark-lint-no-auto-link-without-protocol": "^2.0.0",
+		"remark-lint-no-blockquote-without-marker": "^3.0.0",
+		"remark-lint-no-emphasis-as-heading": "^2.0.0",
+		"remark-lint-no-empty-sections": "^4.0.0",
 		"remark-lint-no-file-name-articles": "^1.0.2",
 		"remark-lint-no-file-name-consecutive-dashes": "^1.0.2",
 		"remark-lint-no-file-name-irregular-characters": "^1.0.2",
 		"remark-lint-no-file-name-mixed-case": "^1.0.2",
 		"remark-lint-no-file-name-outer-dashes": "^1.0.3",
-		"remark-lint-no-heading-content-indent": "^1.0.2",
-		"remark-lint-no-heading-indent": "^1.0.2",
-		"remark-lint-no-heading-punctuation": "^1.0.2",
-		"remark-lint-no-inline-padding": "^1.0.2",
-		"remark-lint-no-multiple-toplevel-headings": "^1.0.2",
+		"remark-lint-no-heading-content-indent": "^2.0.0",
+		"remark-lint-no-heading-indent": "^2.0.0",
+		"remark-lint-no-heading-punctuation": "^2.0.0",
+		"remark-lint-no-inline-padding": "^2.0.0",
+		"remark-lint-no-multiple-toplevel-headings": "^2.0.0",
 		"remark-lint-no-repeat-punctuation": "^0.1.3",
-		"remark-lint-no-shell-dollars": "^1.0.2",
-		"remark-lint-no-table-indentation": "^1.0.2",
-		"remark-lint-no-undefined-references": "^1.0.2",
-		"remark-lint-no-unneeded-full-reference-image": "^1.0.0",
-		"remark-lint-no-unneeded-full-reference-link": "^1.0.0",
-		"remark-lint-no-unused-definitions": "^1.0.2",
-		"remark-lint-ordered-list-marker-style": "^1.0.2",
-		"remark-lint-ordered-list-marker-value": "^1.0.2",
-		"remark-lint-rule-style": "^1.0.2",
-		"remark-lint-strong-marker": "^1.0.2",
-		"remark-lint-table-cell-padding": "^1.0.2",
-		"remark-lint-table-pipe-alignment": "^1.0.2",
-		"remark-lint-table-pipes": "^1.0.2",
-		"remark-lint-unordered-list-marker-style": "^1.0.2",
+		"remark-lint-no-shell-dollars": "^2.0.1",
+		"remark-lint-no-table-indentation": "^2.0.0",
+		"remark-lint-no-undefined-references": "^2.0.0",
+		"remark-lint-no-unneeded-full-reference-image": "^2.0.0",
+		"remark-lint-no-unneeded-full-reference-link": "^2.0.0",
+		"remark-lint-no-unused-definitions": "^2.0.0",
+		"remark-lint-ordered-list-marker-style": "^2.0.0",
+		"remark-lint-ordered-list-marker-value": "^2.0.0",
+		"remark-lint-rule-style": "^2.0.0",
+		"remark-lint-strong-marker": "^2.0.0",
+		"remark-lint-table-cell-padding": "^2.0.0",
+		"remark-lint-table-pipe-alignment": "^2.0.0",
+		"remark-lint-table-pipes": "^2.0.0",
+		"remark-lint-unordered-list-marker-style": "^2.0.0",
 		"rmfr": "^2.0.0",
-		"tempy": "^0.3.0",
+		"tempy": "^0.5.0",
 		"to-vfile": "^6.0.0",
 		"unified-lint-rule": "^1.0.3",
 		"unist-util-find": "^1.0.1",
-		"unist-util-find-all-after": "^2.0.0",
+		"unist-util-find-all-after": "^3.0.1",
 		"unist-util-find-all-before": "^2.0.2",
 		"unist-util-find-all-between": "^2.0.0",
 		"unist-util-visit": "^2.0.1",
-		"vfile-reporter-pretty": "^3.0.0"
+		"vfile-reporter-pretty": "^4.0.0"
 	},
 	"devDependencies": {
 		"ava": "^2.4.0",
-		"sinon": "^7.2.3",
-		"xo": "^0.25.3"
+		"sinon": "^9.0.2",
+		"xo": "^0.30.0"
 	}
 }
diff --git a/readme.md b/readme.md
index a22195a..4e1bf89 100644
--- a/readme.md
+++ b/readme.md
@@ -8,7 +8,7 @@
 
 > Linter for [Awesome](https://awesome.re) lists
 
-[![Build Status](https://travis-ci.org/sindresorhus/awesome-lint.svg?branch=master)](https://travis-ci.org/sindresorhus/awesome-lint)
+[![Build Status](https://travis-ci.com/sindresorhus/awesome-lint.svg?branch=master)](https://travis-ci.com/sindresorhus/awesome-lint)
 
 Intended to make it easier to create and maintain Awesome lists.
 
@@ -16,7 +16,6 @@ Includes a bunch of [general Markdown rules](https://github.com/sindresorhus/awe
 
 ![](media/screenshot.png)
 
-
 ## CLI
 
 ### Install
@@ -149,13 +148,7 @@ Returns a `Promise` for a list of [`VFile`](https://github.com/wooorm/vfile) obj
 
 Show the lint output. This can be custom reported by setting `options.reporter=<function>` and passing in `options` as a parameter.
 
-
 ## Maintainers
 
-- [Sindre Sorhus](http://github.com/sindresorhus)
+- [Sindre Sorhus](https://github.com/sindresorhus)
 - [Travis Fischer](https://github.com/transitive-bullshit)
-
-
-## License
-
-MIT
diff --git a/rules/contributing.js b/rules/contributing.js
index a96552f..693be33 100644
--- a/rules/contributing.js
+++ b/rules/contributing.js
@@ -7,7 +7,7 @@ const rule = require('unified-lint-rule');
 module.exports = rule('remark-lint:awesome-contributing', (ast, file) => {
 	const {dirname} = file;
 
-	const contributingFile = globby.sync(['contributing.md', 'CONTRIBUTING.md'], {cwd: dirname})[0];
+	const contributingFile = globby.sync(['{.github/,}contributing.md'], {nocase: true, cwd: dirname})[0];
 	// TODO: This doesn't work on Linux for some reason. Investigate and then open an issue on `fast-glob`.
 	// const contributingFile = globby.sync('contributing.md', {case: false, cwd: dirname})[0];
 
diff --git a/rules/github.js b/rules/github.js
index b54d513..cf8d2cf 100644
--- a/rules/github.js
+++ b/rules/github.js
@@ -30,9 +30,9 @@ module.exports = rule('remark-lint:awesome-github', async (ast, file) => {
 			headers.Authorization = `token ${process.env.github_token}`;
 		}
 
-		let res;
+		let response;
 		try {
-			res = await got.get(githubUrls.api_url, {
+			response = await got.get(githubUrls.api_url, {
 				headers,
 				json: true
 			});
@@ -53,7 +53,7 @@ module.exports = rule('remark-lint:awesome-github', async (ast, file) => {
 			return;
 		}
 
-		const data = res.body;
+		const data = response.body;
 		if (!data.description) {
 			file.message('The repository should have a description');
 		}
diff --git a/rules/list-item.js b/rules/list-item.js
index 87ce47d..da6688e 100644
--- a/rules/list-item.js
+++ b/rules/list-item.js
@@ -181,7 +181,7 @@ function validateListItemDescription(description, file) {
 		return false;
 	}
 
-	// Ensure description ends with '.', '!', '?' or an acceptable special-case
+	// Ensure description ends with '.', '!', '?', '…' or an acceptable special-case
 	if (suffix.type === 'text' && !validateListItemSuffix(descriptionText, suffixText)) {
 		file.message('List item description must end with proper punctuation', suffix);
 		return false;
@@ -276,8 +276,8 @@ function validateListItemPrefix(descriptionText, prefixText) {
 }
 
 function validateListItemSuffix(descriptionText, suffixText) {
-	if (/[.!?]\s*$/.test(suffixText)) {
-		// Description ends with '.', '!', or '?'
+	if (/[.!?…]\s*$/.test(suffixText)) {
+		// Description ends with '.', '!', '?' or '…'
 		return true;
 	}
 
diff --git a/rules/spell-check.js b/rules/spell-check.js
index a117291..037e7f4 100644
--- a/rules/spell-check.js
+++ b/rules/spell-check.js
@@ -26,10 +26,10 @@ module.exports = rule('remark-lint:awesome-spell-check', (ast, file) => {
 					}
 
 					if (match[0] !== value) {
-						const prevCharacter = node.value[match.index - 1];
+						const previousCharacter = node.value[match.index - 1];
 						const nextCharacter = node.value[match.index + match[0].length];
 
-						if (wordBreakCharacterWhitelist.has(prevCharacter)) {
+						if (wordBreakCharacterWhitelist.has(previousCharacter)) {
 							continue;
 						}
 


Test patch:
diff --git a/test/fixtures/license/error4.md b/test/fixtures/license/error4.md
index 2b6228f..1c123d8 100644
--- a/test/fixtures/license/error4.md
+++ b/test/fixtures/license/error4.md
@@ -1,5 +1,5 @@
 ## License
 
-[![CC4](https://mirrors.creativecommons.org/presskit/buttons/88x31/png/by.png)](http://creativecommons.org/licenses/by/4.0/)
+[![CC4](https://mirrors.creativecommons.org/presskit/buttons/88x31/png/by.png)](https://creativecommons.org/licenses/by/4.0/)
 
 This license is invalid because it points to a png instead of an svg.
diff --git a/test/fixtures/license/success0.md b/test/fixtures/license/success0.md
index d34b934..15b4b3c 100644
--- a/test/fixtures/license/success0.md
+++ b/test/fixtures/license/success0.md
@@ -10,6 +10,6 @@ This license section below is 100% valid.
 
 ## License
 
-[![CC0](http://mirrors.creativecommons.org/presskit/buttons/88x31/svg/cc-zero.svg)](https://creativecommons.org/publicdomain/zero/1.0/)
+[![CC0](https://mirrors.creativecommons.org/presskit/buttons/88x31/svg/cc-zero.svg)](https://creativecommons.org/publicdomain/zero/1.0/)
 
-To the extent possible under law, [Sindre Sorhus](http://sindresorhus.com) has waived all copyright and related or neighboring rights to this work.
+To the extent possible under law, [Sindre Sorhus](https://sindresorhus.com) has waived all copyright and related or neighboring rights to this work.
diff --git a/test/fixtures/list-item/0.md b/test/fixtures/list-item/0.md
index ae3d11a..1ea9e3d 100644
--- a/test/fixtures/list-item/0.md
+++ b/test/fixtures/list-item/0.md
@@ -3,13 +3,14 @@ All list-items in this document should be linted as **valid**.
 - [foo](https://foo.com) - Valid description.
 - [foo](https://foo.com) - A valid description.
 - [foo](https://foo.com) - A valid description...
+- [foo](https://foo.com) - A valid description…
 - [foo](https://foo.com) - A valid description!
 - [foo](https://foo.com) - A valid description! ⭐
 - [foo](https://foo.com) - A valid description!!!
 - [foo](https://foo.com) - A valid description?
 - [foo](https://foo.com) - A valid description???
 - [foo](https://foo.com) - A valid description????!??
-- [foo](https://foo.com) - A valid description with [link](http://bar.org).
+- [foo](https://foo.com) - A valid description with [link](https://bar.org).
 - [foo](https://foo.com) - A valid description. ![image](image.png)
 - [foo](https://foo.com) - A valid description. <img src="image.png">
 - [foo](https://foo.com) - `valid description` here.
@@ -24,12 +25,12 @@ All list-items in this document should be linted as **valid**.
 
 These are valid list items that don't need a description.
 
-- [How to Write a Video Player in Less Than 1k Lines](http://dranger.com/ffmpeg)
+- [How to Write a Video Player in Less Than 1k Lines](https://dranger.com/ffmpeg)
 - [Learn FFmpeg libav the Hard Way](https://github.com/leandromoreira/ffmpeg-libav-tutorial)
 
 ## Edge Cases
 
-- [dat](http://dat-data.com) - Real-time replication and versioning for data sets.
+- [dat](https://dat-data.com) - Real-time replication and versioning for data sets.
 - [webcat](https://github.com/mafintosh/webcat) - p2p pipe across the web using WebRTC that uses your GitHub private/public key for authentication.
 - [Brain.js](https://github.com/BrainJS/brain.js) - Machine-learning framework.
 - [Cash](https://github.com/dthree/cash) - Cross-platform Unix shell commands in pure JavaScript.
@@ -66,7 +67,7 @@ These list items are special-cases which have simple descripitions and no dash s
 
 These list items use inline code in the link text.
 - [`@electronjs` on Twitter](https://twitter.com/electronjs)
-- [`#node.js` on Freenode](http://webchat.freenode.net/?channels=node.js)
+- [`#node.js` on Freenode](https://webchat.freenode.net/?channels=node.js)
 - [`@electron_ru` on Telegram](https://telegram.me/electron_ru) *(Russian)*
 
 These list items start with common lower-case acronyms.
diff --git a/test/fixtures/list-item/2.md b/test/fixtures/list-item/2.md
index b224d9f..ad083e5 100644
--- a/test/fixtures/list-item/2.md
+++ b/test/fixtures/list-item/2.md
@@ -11,4 +11,4 @@ We want to ensure that ToC list-items don't get linted by the awesome/list-item
 ## Docs
 
 - [foo](https://foo.com) - Valid description.
-- [foo](https://foo.com) - A valid description with [link](http://bar.org).
+- [foo](https://foo.com) - A valid description with [link](https://bar.org).
diff --git a/test/fixtures/toc/6.md b/test/fixtures/toc/6.md
index 8a08e06..945f44c 100644
--- a/test/fixtures/toc/6.md
+++ b/test/fixtures/toc/6.md
@@ -5,19 +5,6 @@
 	<p>
 		<a href="https://www.patreon.com/sindresorhus">My open source work is supported by the community</a>
 	</p>
-	<p>
-		<sup>Special thanks to:</sup>
-		<br>
-		<br>
-		<a href="https://github.com/wtgtybhertgeghgtwtg">
-			<img src="https://cdn.jsdelivr.net/gh/sindresorhus/stuff@daa49fabede538ea8a533d75e7e55f4c81e3a972/sponsors/wtgtybhertgeghgtwtg-logo-light.svg" width="260"  alt="wtgtybhertgeghgtwtg">
-		</a>
-		<br>
-		<br>
-		<a href="https://github.com/botpress/botpress">
-			<img src="https://sindresorhus.com/assets/thanks/botpress-logo.svg" width="240" alt="Botpress">
-		</a>
-	</p>
 	<br>
 	<br>
 </div>
diff --git a/test/rules/code-of-conduct.js b/test/rules/code-of-conduct.js
index f744809..294318a 100644
--- a/test/rules/code-of-conduct.js
+++ b/test/rules/code-of-conduct.js
@@ -34,7 +34,7 @@ test('code-of-conduct - invalid if just copyed', async t => {
 	const messages = await lint({config, filename: 'test/fixtures/code-of-conduct/error2/readme.md'});
 	t.deepEqual(messages, [
 		{
-			line: 57,
+			line: 58,
 			ruleId: 'awesome-code-of-conduct',
 			message: 'The default email must be replaced with yours'
 		}