From 4fa837a0310d1320c0644cf2fbd0e2b09abce112 Mon Sep 17 00:00:00 2001 From: Duncan Mackenzie Date: Fri, 29 Dec 2017 17:01:21 -0800 Subject: [PATCH 1/2] Add MD045/no-alt-text (fixes #75). --- README.md | 3 ++ doc/Rules.md | 10 +++++++ lib/rules.js | 18 ++++++++++++ schema/markdownlint-config-schema.json | 20 +++++++++++++ test/detailed-results-MD041-MD050.md | 8 +++++ .../detailed-results-MD041-MD050.results.json | 29 ++++++++++++++++++- test/markdownlint-test.js | 8 ++--- test/no-alt-text.md | 3 ++ 8 files changed, 94 insertions(+), 5 deletions(-) create mode 100644 test/no-alt-text.md diff --git a/README.md b/README.md index 3a257530..a4ed243e 100644 --- a/README.md +++ b/README.md @@ -86,11 +86,13 @@ playground for learning and exploring. * **[MD042](doc/Rules.md#md042)** *no-empty-links* - No empty links * **[MD043](doc/Rules.md#md043)** *required-headers* - Required header structure * **[MD044](doc/Rules.md#md044)** *proper-names* - Proper names should have the correct capitalization +* **[MD045](doc/Rules.md#md045)** *no-alt-text* - Images should have ALT Text attribute See [Rules.md](doc/Rules.md) for more details. ## Tags +* **accessibility** - MD045 * **atx** - MD018, MD019 * **atx_closed** - MD020, MD021 * **blank_lines** - MD012, MD022, MD031, MD032 @@ -103,6 +105,7 @@ See [Rules.md](doc/Rules.md) for more details. MD024, MD025, MD026, MD036, MD041, MD043 * **hr** - MD035 * **html** - MD033 +* **images** - MD045 * **indentation** - MD005, MD006, MD007, MD027 * **language** - MD040 * **line_length** - MD013 diff --git a/doc/Rules.md b/doc/Rules.md index b73b66e8..9845b1e6 100644 --- a/doc/Rules.md +++ b/doc/Rules.md @@ -1243,3 +1243,13 @@ the proper capitalization, specify the desired letter case in the `names` array: ] Set the `code_blocks` parameter to `false` to disable this rule for code blocks. + + + +## MD045 - Images should have ALT Text attribute + +Tags: accessibility, images + +Aliases: no-alt-text + +This rule is triggered when an image is found with no alt text. This is a key concern for accessibility. [Guidance on how to write alt text for images](https://www.phase2technology.com/blog/no-more-excuses-definitive-guide-alt-text-field). diff --git a/lib/rules.js b/lib/rules.js index 613d0800..9f2f75d8 100644 --- a/lib/rules.js +++ b/lib/rules.js @@ -1219,5 +1219,23 @@ module.exports = [ } }); } + }, + { + "name": "MD045", + "desc": "Images should have ALT Text attribute", + "tags": [ "accessibility", "images" ], + "aliases": [ "no-alt-text" ], + "regexp": null, + "func": function MD045(params, errors) { + forEachInlineChild(params, "image", function forToken(token) { + if (token.content === "") { + token.attrs.forEach(function forAttr(attr) { + if (attr[0] === "alt" && attr[1] === "") { + errors.add(token.lineNumber); + } + }); + } + }); + } } ]; diff --git a/schema/markdownlint-config-schema.json b/schema/markdownlint-config-schema.json index a4c2a81c..c7ccac35 100644 --- a/schema/markdownlint-config-schema.json +++ b/schema/markdownlint-config-schema.json @@ -956,6 +956,16 @@ }, "additionalProperties": false }, + "MD045": { + "description": "MD045/no-alt-text - Images should have ALT Text attribute", + "type": "boolean", + "default": true + }, + "no-alt-text": { + "description": "MD045/no-alt-text - Images should have ALT Text attribute", + "type": "boolean", + "default": true + }, "headers": { "description": "headers - MD001, MD002, MD003, MD018, MD019, MD020, MD021, MD022, MD023, MD024, MD025, MD026, MD036, MD041, MD043", "type": "boolean", @@ -1060,6 +1070,16 @@ "description": "spelling - MD044", "type": "boolean", "default": true + }, + "images": { + "description": "images - MD045", + "type": "boolean", + "default": true + }, + "accessibility": { + "description": "accessibility - MD045", + "type": "boolean", + "default": true } }, "additionalProperties": false diff --git a/test/detailed-results-MD041-MD050.md b/test/detailed-results-MD041-MD050.md index a19515d3..ad2911ce 100644 --- a/test/detailed-results-MD041-MD050.md +++ b/test/detailed-results-MD041-MD050.md @@ -15,3 +15,11 @@ name wrong twice: MarkDownLint. A [normal](link) and an [empty one]() and a [fragment](#one). + +An image without alt text ![](image.jpg) + +![](image.jpg) + +A reference image without alt text ![][reference] + +[reference]: image.jpg "title" \ No newline at end of file diff --git a/test/detailed-results-MD041-MD050.results.json b/test/detailed-results-MD041-MD050.results.json index 2a74d2a9..9558a3d9 100644 --- a/test/detailed-results-MD041-MD050.results.json +++ b/test/detailed-results-MD041-MD050.results.json @@ -45,7 +45,7 @@ "errorRange": [25, 13] }, { - "lineNumber": 18, + "lineNumber": 25, "ruleName": "MD043", "ruleAlias": "required-headers", "ruleDescription": "Required header structure", @@ -79,5 +79,32 @@ "errorDetail": "Expected: markdownlint; Actual: MarkDownLint", "errorContext": null, "errorRange": [1, 12] + }, + { + "lineNumber": 19, + "ruleName": "MD045", + "ruleAlias": "no-alt-text", + "ruleDescription": "Images should have ALT Text attribute", + "errorDetail": null, + "errorContext": null, + "errorRange": null + }, + { + "lineNumber": 21, + "ruleName": "MD045", + "ruleAlias": "no-alt-text", + "ruleDescription": "Images should have ALT Text attribute", + "errorDetail": null, + "errorContext": null, + "errorRange": null + }, + { + "lineNumber": 23, + "ruleName": "MD045", + "ruleAlias": "no-alt-text", + "ruleDescription": "Images should have ALT Text attribute", + "errorDetail": null, + "errorContext": null, + "errorRange": null } ] \ No newline at end of file diff --git a/test/markdownlint-test.js b/test/markdownlint-test.js index 917c7cb1..26689bc7 100644 --- a/test/markdownlint-test.js +++ b/test/markdownlint-test.js @@ -965,7 +965,7 @@ module.exports.missingStringValue = function missingStringValue(test) { }; module.exports.ruleNamesUpperCase = function ruleNamesUpperCase(test) { - test.expect(40); + test.expect(41); rules.forEach(function forRule(rule) { test.equal(rule.name, rule.name.toUpperCase(), "Rule name not upper-case."); }); @@ -973,7 +973,7 @@ module.exports.ruleNamesUpperCase = function ruleNamesUpperCase(test) { }; module.exports.uniqueAliases = function uniqueAliases(test) { - test.expect(80); + test.expect(82); var tags = []; rules.forEach(function forRule(rule) { Array.prototype.push.apply(tags, rule.tags); @@ -990,7 +990,7 @@ module.exports.uniqueAliases = function uniqueAliases(test) { }; module.exports.readme = function readme(test) { - test.expect(104); + test.expect(108); var tagToRules = {}; rules.forEach(function forRule(rule) { rule.tags.forEach(function forTag(tag) { @@ -1052,7 +1052,7 @@ module.exports.readme = function readme(test) { }; module.exports.doc = function doc(test) { - test.expect(303); + test.expect(310); fs.readFile("doc/Rules.md", shared.utf8Encoding, function readFile(err, contents) { test.ifError(err); diff --git a/test/no-alt-text.md b/test/no-alt-text.md new file mode 100644 index 00000000..a05e2094 --- /dev/null +++ b/test/no-alt-text.md @@ -0,0 +1,3 @@ +# This is an image link without any alt text + +![](image.jpg) {MD045} \ No newline at end of file From f91f0880c31703cd0ea3256c1362a84853561cc3 Mon Sep 17 00:00:00 2001 From: David Anson Date: Sat, 6 Jan 2018 18:06:32 -0800 Subject: [PATCH 2/2] Refine implementation of MD045/no-alt-text in previous commit. --- README.md | 2 +- doc/Rules.md | 26 ++++++++++++++++-- lib/rules.js | 8 ++---- schema/markdownlint-config-schema.json | 12 ++++----- test/detailed-results-MD041-MD050.md | 8 +----- .../detailed-results-MD041-MD050.results.json | 22 ++------------- test/no-alt-text.md | 27 +++++++++++++++++-- 7 files changed, 61 insertions(+), 44 deletions(-) diff --git a/README.md b/README.md index a4ed243e..e00182a0 100644 --- a/README.md +++ b/README.md @@ -86,7 +86,7 @@ playground for learning and exploring. * **[MD042](doc/Rules.md#md042)** *no-empty-links* - No empty links * **[MD043](doc/Rules.md#md043)** *required-headers* - Required header structure * **[MD044](doc/Rules.md#md044)** *proper-names* - Proper names should have the correct capitalization -* **[MD045](doc/Rules.md#md045)** *no-alt-text* - Images should have ALT Text attribute +* **[MD045](doc/Rules.md#md045)** *no-alt-text* - Images should have alternate text (alt text) See [Rules.md](doc/Rules.md) for more details. diff --git a/doc/Rules.md b/doc/Rules.md index 9845b1e6..67224365 100644 --- a/doc/Rules.md +++ b/doc/Rules.md @@ -1246,10 +1246,32 @@ Set the `code_blocks` parameter to `false` to disable this rule for code blocks. -## MD045 - Images should have ALT Text attribute +## MD045 - Images should have alternate text (alt text) Tags: accessibility, images Aliases: no-alt-text -This rule is triggered when an image is found with no alt text. This is a key concern for accessibility. [Guidance on how to write alt text for images](https://www.phase2technology.com/blog/no-more-excuses-definitive-guide-alt-text-field). +This rule is triggered when an image is missing alternate text (alt text) information. +Alternate text is important for accessibility, describing the content of an image for +people who may not be able to see it. + +Alternate text is commonly specified inline as: + +```md +![Alternate text](image.jpg) +``` + +Or with reference syntax as: + +```md +![Alternate text][ref] + +... + +[ref]: image.jpg "Optional title" +``` + +Guidance for writing alternate text is available from the [W3C](https://www.w3.org/WAI/alt/), +[Wikipedia](https://en.wikipedia.org/wiki/Alt_attribute), and +[other locations](https://www.phase2technology.com/blog/no-more-excuses-definitive-guide-alt-text-field). diff --git a/lib/rules.js b/lib/rules.js index 9f2f75d8..52ce57ad 100644 --- a/lib/rules.js +++ b/lib/rules.js @@ -1222,18 +1222,14 @@ module.exports = [ }, { "name": "MD045", - "desc": "Images should have ALT Text attribute", + "desc": "Images should have alternate text (alt text)", "tags": [ "accessibility", "images" ], "aliases": [ "no-alt-text" ], "regexp": null, "func": function MD045(params, errors) { forEachInlineChild(params, "image", function forToken(token) { if (token.content === "") { - token.attrs.forEach(function forAttr(attr) { - if (attr[0] === "alt" && attr[1] === "") { - errors.add(token.lineNumber); - } - }); + errors.add(token.lineNumber); } }); } diff --git a/schema/markdownlint-config-schema.json b/schema/markdownlint-config-schema.json index c7ccac35..2c01631c 100644 --- a/schema/markdownlint-config-schema.json +++ b/schema/markdownlint-config-schema.json @@ -957,12 +957,12 @@ "additionalProperties": false }, "MD045": { - "description": "MD045/no-alt-text - Images should have ALT Text attribute", + "description": "MD045/no-alt-text - Images should have alternate text (alt text)", "type": "boolean", "default": true }, "no-alt-text": { - "description": "MD045/no-alt-text - Images should have ALT Text attribute", + "description": "MD045/no-alt-text - Images should have alternate text (alt text)", "type": "boolean", "default": true }, @@ -1071,13 +1071,13 @@ "type": "boolean", "default": true }, - "images": { - "description": "images - MD045", + "accessibility": { + "description": "accessibility - MD045", "type": "boolean", "default": true }, - "accessibility": { - "description": "accessibility - MD045", + "images": { + "description": "images - MD045", "type": "boolean", "default": true } diff --git a/test/detailed-results-MD041-MD050.md b/test/detailed-results-MD041-MD050.md index ad2911ce..31b027b4 100644 --- a/test/detailed-results-MD041-MD050.md +++ b/test/detailed-results-MD041-MD050.md @@ -16,10 +16,4 @@ MarkDownLint. A [normal](link) and an [empty one]() and a [fragment](#one). -An image without alt text ![](image.jpg) - -![](image.jpg) - -A reference image without alt text ![][reference] - -[reference]: image.jpg "title" \ No newline at end of file +An image without alternate text ![](image.jpg) diff --git a/test/detailed-results-MD041-MD050.results.json b/test/detailed-results-MD041-MD050.results.json index 9558a3d9..252138a6 100644 --- a/test/detailed-results-MD041-MD050.results.json +++ b/test/detailed-results-MD041-MD050.results.json @@ -45,7 +45,7 @@ "errorRange": [25, 13] }, { - "lineNumber": 25, + "lineNumber": 20, "ruleName": "MD043", "ruleAlias": "required-headers", "ruleDescription": "Required header structure", @@ -84,25 +84,7 @@ "lineNumber": 19, "ruleName": "MD045", "ruleAlias": "no-alt-text", - "ruleDescription": "Images should have ALT Text attribute", - "errorDetail": null, - "errorContext": null, - "errorRange": null - }, - { - "lineNumber": 21, - "ruleName": "MD045", - "ruleAlias": "no-alt-text", - "ruleDescription": "Images should have ALT Text attribute", - "errorDetail": null, - "errorContext": null, - "errorRange": null - }, - { - "lineNumber": 23, - "ruleName": "MD045", - "ruleAlias": "no-alt-text", - "ruleDescription": "Images should have ALT Text attribute", + "ruleDescription": "Images should have alternate text (alt text)", "errorDetail": null, "errorContext": null, "errorRange": null diff --git a/test/no-alt-text.md b/test/no-alt-text.md index a05e2094..768e537c 100644 --- a/test/no-alt-text.md +++ b/test/no-alt-text.md @@ -1,3 +1,26 @@ -# This is an image link without any alt text +# Images with and without alternate text -![](image.jpg) {MD045} \ No newline at end of file +![Alternate text](image.jpg) + +![](image.jpg) {MD045} + +![Alternate text](image.jpg "Title") + +![](image.jpg "Title") {MD045} + +Image without alternate text ![](image.jpg) in a sentence. {MD045} + +Reference image with alternate text ![Alternate text][notitle] + +Reference image without alternate text ![][notitle] {MD045} + +Reference image with alternate text and title ![Alternate text][title] + +Reference image without alternate text and title ![][title] {MD045} + +Link to image with alternate text [![Alternate text](image.jpg)](image.jpg) + +Link to image without alternate text [![](image.jpg)](image.jpg) {MD045} + +[notitle]: image.jpg +[title]: image.jpg "Title"