Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add HTML support for MD045: no-alt-text #993

Merged
merged 30 commits into from
Oct 19, 2023
Merged
Show file tree
Hide file tree
Changes from 25 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
a43cb2a
Add support for missing alt on HTML image tag
khiga8 Oct 4, 2023
e688dfb
Update tests
khiga8 Oct 5, 2023
9cf6579
Update doc
khiga8 Oct 5, 2023
778033c
Add multiline support
khiga8 Oct 5, 2023
181744a
set error on the tag
khiga8 Oct 5, 2023
aa18bcb
Add alt text to unrelated tests
khiga8 Oct 5, 2023
7adf938
Run docs script
khiga8 Oct 5, 2023
e75f92c
add space between rules
khiga8 Oct 5, 2023
f9c8b91
Case insensitive comparison
khiga8 Oct 5, 2023
d874841
Regenerate snapshots
khiga8 Oct 5, 2023
7538efc
Add case insensitive tests
khiga8 Oct 5, 2023
33a6654
This file got updated when running npm run ci
khiga8 Oct 5, 2023
c004a05
Update snapshots
khiga8 Oct 5, 2023
0165cf5
Update docs
khiga8 Oct 17, 2023
d5ea305
Move regex to shared helper
khiga8 Oct 17, 2023
c7c20d2
Rename variables
khiga8 Oct 17, 2023
af6ee6d
Update alt regex
khiga8 Oct 17, 2023
54b5c1b
Switch to undefined
khiga8 Oct 17, 2023
62166e6
Switch order of alt and src in img tag.
khiga8 Oct 17, 2023
8d7e920
Update tests to use XHTML, embedded images
khiga8 Oct 17, 2023
63727f1
Add space in docs
khiga8 Oct 17, 2023
a9e4456
Add test for single quote and update language
khiga8 Oct 17, 2023
93fd67e
Update alt and src order
khiga8 Oct 17, 2023
26bc7af
Run npm run build-demo
khiga8 Oct 17, 2023
c5fb4b8
Rerun repo snapshots
khiga8 Oct 17, 2023
9042fe5
Update helpers.js
DavidAnson Oct 18, 2023
79c7d73
Update md045.js
DavidAnson Oct 18, 2023
06470ca
Update markdownlint-browser.js
DavidAnson Oct 18, 2023
3149eae
Update markdownlint-browser.js
DavidAnson Oct 18, 2023
a1db76d
Rerun build-demo sript
khiga8 Oct 18, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 35 additions & 5 deletions demo/markdownlint-browser.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,10 @@ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" ==
var micromark = __webpack_require__(/*! ./micromark.cjs */ "../helpers/micromark.cjs");
var _require = __webpack_require__(/*! ./shared.js */ "../helpers/shared.js"),
newLineRe = _require.newLineRe;
var _require2 = __webpack_require__(/*! ./shared.js */ "../helpers/shared.js"),
nextLinesRe = _require2.nextLinesRe;
module.exports.newLineRe = newLineRe;
module.exports.nextLinesRe = nextLinesRe;

// Regular expression for matching common front matter (YAML and TOML)
module.exports.frontMatterRe =
Expand Down Expand Up @@ -1064,6 +1067,9 @@ module.exports.expandTildePath = expandTildePath;
// See NEWLINES_RE in markdown-it/lib/rules_core/normalize.js
module.exports.newLineRe = /\r\n?|\n/g;

// Regular expression for matching next lines
module.exports.nextLinesRe = /[\r\n][\s\S]*$/;

/***/ }),

/***/ "markdown-it":
Expand Down Expand Up @@ -5043,11 +5049,11 @@ function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
var _require = __webpack_require__(/*! ../helpers */ "../helpers/helpers.js"),
addError = _require.addError;
addError = _require.addError,
nextLinesRe = _require.nextLinesRe;
var _require2 = __webpack_require__(/*! ../helpers/micromark.cjs */ "../helpers/micromark.cjs"),
filterByTypes = _require2.filterByTypes,
getHtmlTagInfo = _require2.getHtmlTagInfo;
var nextLinesRe = /[\r\n][\s\S]*$/;
module.exports = {
"names": ["MD033", "no-inline-html"],
"description": "Inline HTML",
Expand Down Expand Up @@ -5986,15 +5992,21 @@ function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
var _require = __webpack_require__(/*! ../helpers */ "../helpers/helpers.js"),
addError = _require.addError;
addError = _require.addError,
nextLinesRe = _require.nextLinesRe;
var _require2 = __webpack_require__(/*! ../helpers/micromark.cjs */ "../helpers/micromark.cjs"),
filterByTypes = _require2.filterByTypes;
filterByTypes = _require2.filterByTypes,
getHtmlTagInfo = _require2.getHtmlTagInfo;

// Regular expression for identifying alt attribute
var altRe = /\salt=/i;
module.exports = {
"names": ["MD045", "no-alt-text"],
"description": "Images should have alternate text (alt text)",
"tags": ["accessibility", "images"],
"function": function MD045(params, onError) {
var images = filterByTypes(params.parsers.micromark.tokens, ["image"]);
var tokens = params.parsers.micromark.tokens;
var images = filterByTypes(tokens, ["image"]);
var _iterator = _createForOfIteratorHelper(images),
_step;
try {
Expand All @@ -6013,6 +6025,24 @@ module.exports = {
} finally {
_iterator.f();
}
var htmls = filterByTypes(tokens, ["htmlText"]);
var _iterator2 = _createForOfIteratorHelper(htmls),
_step2;
try {
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
var html = _step2.value;
var htmlTagInfo = getHtmlTagInfo(html);
var isImage = htmlTagInfo && htmlTagInfo.name.toLowerCase() === "img";
if (isImage && !altRe.test(html.text)) {
var _range = [html.startColumn, html.text.replace(nextLinesRe, "").length];
addError(onError, html.startLine, undefined, undefined, _range);
}
}
} catch (err) {
_iterator2.e(err);
} finally {
_iterator2.f();
}
}
};

Expand Down
6 changes: 6 additions & 0 deletions doc-build/md045.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ Or with reference syntax as:
[ref]: image.jpg "Optional title"
```

Or with HTML as:

```html
<img src="image.jpg" alt="Alternate text" />
```

Guidance for writing alternate text is available from the [W3C][w3c],
[Wikipedia][wikipedia], and [other locations][phase2technology].

Expand Down
6 changes: 6 additions & 0 deletions doc/Rules.md
Original file line number Diff line number Diff line change
Expand Up @@ -1955,6 +1955,12 @@ Or with reference syntax as:
[ref]: image.jpg "Optional title"
```

Or with HTML as:

```html
<img src="image.jpg" alt="Alternate text" />
```

Guidance for writing alternate text is available from the [W3C][w3c],
[Wikipedia][wikipedia], and [other locations][phase2technology].

Expand Down
6 changes: 6 additions & 0 deletions doc/md045.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ Or with reference syntax as:
[ref]: image.jpg "Optional title"
```

Or with HTML as:

```html
<img src="image.jpg" alt="Alternate text" />
```

Guidance for writing alternate text is available from the [W3C][w3c],
[Wikipedia][wikipedia], and [other locations][phase2technology].

Expand Down
3 changes: 3 additions & 0 deletions helpers/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@
const micromark = require("./micromark.cjs");

const { newLineRe } = require("./shared.js");
const { nextLinesRe } = require("./shared.js");
DavidAnson marked this conversation as resolved.
Show resolved Hide resolved

module.exports.newLineRe = newLineRe;
module.exports.nextLinesRe = nextLinesRe;

// Regular expression for matching common front matter (YAML and TOML)
module.exports.frontMatterRe =
Expand Down
3 changes: 3 additions & 0 deletions helpers/shared.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,6 @@
// Regular expression for matching common newline characters
// See NEWLINES_RE in markdown-it/lib/rules_core/normalize.js
module.exports.newLineRe = /\r\n?|\n/g;

// Regular expression for matching next lines
module.exports.nextLinesRe = /[\r\n][\s\S]*$/;
4 changes: 1 addition & 3 deletions lib/md033.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,10 @@

"use strict";

const { addError } = require("../helpers");
const { addError, nextLinesRe } = require("../helpers");
const { filterByTypes, getHtmlTagInfo } =
require("../helpers/micromark.cjs");

const nextLinesRe = /[\r\n][\s\S]*$/;

module.exports = {
"names": [ "MD033", "no-inline-html" ],
"description": "Inline HTML",
Expand Down
29 changes: 26 additions & 3 deletions lib/md045.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,19 @@

"use strict";

const { addError } = require("../helpers");
const { filterByTypes } = require("../helpers/micromark.cjs");
const { addError, nextLinesRe } = require("../helpers");
const { filterByTypes, getHtmlTagInfo } = require("../helpers/micromark.cjs");

// Regular expression for identifying alt attribute
const altRe = /\salt=/i;
DavidAnson marked this conversation as resolved.
Show resolved Hide resolved

module.exports = {
"names": [ "MD045", "no-alt-text" ],
"description": "Images should have alternate text (alt text)",
"tags": [ "accessibility", "images" ],
"function": function MD045(params, onError) {
const images = filterByTypes(params.parsers.micromark.tokens, [ "image" ]);
const tokens = params.parsers.micromark.tokens;
DavidAnson marked this conversation as resolved.
Show resolved Hide resolved
const images = filterByTypes(tokens, [ "image" ]);
for (const image of images) {
const labelTexts = filterByTypes(image.children, [ "labelText" ]);
if (labelTexts.some((labelText) => labelText.text.length === 0)) {
Expand All @@ -26,5 +30,24 @@ module.exports = {
);
}
}

const htmls = filterByTypes(tokens, [ "htmlText" ]);
DavidAnson marked this conversation as resolved.
Show resolved Hide resolved
for (const html of htmls) {
const htmlTagInfo = getHtmlTagInfo(html);
const isImage = htmlTagInfo && htmlTagInfo.name.toLowerCase() === "img";
DavidAnson marked this conversation as resolved.
Show resolved Hide resolved
if (isImage && !altRe.test(html.text)) {
DavidAnson marked this conversation as resolved.
Show resolved Hide resolved
const range = [
html.startColumn,
DavidAnson marked this conversation as resolved.
Show resolved Hide resolved
html.text.replace(nextLinesRe, "").length
];
addError(
onError,
html.startLine,
undefined,
undefined,
range
);
}
}
}
};
2 changes: 1 addition & 1 deletion test/h1-image-as-top-level-heading.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<h1 align="center"><img src="https://placekitten.com/300/150"/></h1>
<h1 align="center"><img src="https://placekitten.com/300/150" alt="A kitten" /></h1>

Text

Expand Down
2 changes: 1 addition & 1 deletion test/html-tags.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ Text ``text <em> text`` text
Text

Text <a href="#anchor">inline {MD033}</a> text
text <img src="src.png"/> text {MD033}
text <img src="src.png" alt="Description" /> text {MD033}

Text

Expand Down
38 changes: 38 additions & 0 deletions test/no-alt-text.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,43 @@ Multi-line image with alternate text ![Alternate text](image.jpg "Title"
Multi-line image without alternate text ![](image.jpg "Title"
) {MD045:28}

DavidAnson marked this conversation as resolved.
Show resolved Hide resolved
<!-- markdownlint-disable no-inline-html -->

Image tag with alt attribute set to text
<img src="image.png" alt="Descriptive text" />

Image tag with alt attribute not set
DavidAnson marked this conversation as resolved.
Show resolved Hide resolved
<img src="image.png" alt> {MD045}

Image tag with alt attribute set to decorative with an empty double-quote string
<img src="image.png" alt="" />

Image tag with alt attribute set to decorative with an empty single-quote string
<img src="image.png" alt='' />

Image tag with no alt attribute <img src="image.png" /> {MD045}

Multi-line image tag with no alt text
DavidAnson marked this conversation as resolved.
Show resolved Hide resolved
<img
src="image.png"> {MD045:48}

Multi-line image tag with alt attribute not set
DavidAnson marked this conversation as resolved.
Show resolved Hide resolved
<img
src="image.png"
alt> {MD045:52}

Multi-line image tag with alt text
<img
src="image.png"
alt="Description"
>

Uppercase image tag with alt attribute set
<IMG SRC="cat.png" ALT="Descriptive text">

Uppercase image tag with no alt set <IMG SRC="cat.png" /> {MD045}

<!-- markdownlint-restore no-inline-html -->

[notitle]: image.jpg
[title]: image.jpg "Title"
2 changes: 1 addition & 1 deletion test/proper-names-no-html.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Bad text javascript. {MD044}

Bad code `javascript`. {MD044}

<img src="img/javascript/image.png">
<img src="img/javascript/image.png" alt="Description">

<script type="text/javascript">
javascript {MD044}
Expand Down
2 changes: 1 addition & 1 deletion test/proper-names.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ Text referencing MultipleCase name.
Text referencing MULTIPLECASE name. {MD044}
Text referencing mULTIPLEcASE name.

<img src="img/javascript/image.png" error="{MD044}">
<img src="img/javascript/image.png" alt="Description" error="{MD044}">

<script type="text/javascript">
{MD044:94}
Expand Down
Binary file modified test/snapshots/markdownlint-test-micromark.mjs.snap
Binary file not shown.
13 changes: 10 additions & 3 deletions test/snapshots/markdownlint-test-repos.js.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Generated by [AVA](https://avajs.dev).

> Expected linting violations

''
'test-repos/apache-airflow/tests/system/providers/apache/hive/example_twitter_README.md: 36: MD045/no-alt-text Images should have alternate text (alt text)'

## https://github.com/dotnet/docs

Expand Down Expand Up @@ -37,7 +37,13 @@ Generated by [AVA](https://avajs.dev).

> Expected linting violations

`test-repos/mdn-content/files/en-us/web/svg/attribute/d/index.md: 234: MD007/ul-indent Unordered list indentation [Expected: 0; Actual: 10]␊
`test-repos/mdn-content/files/en-us/web/css/angle/index.md: 38: MD045/no-alt-text Images should have alternate text (alt text)␊
test-repos/mdn-content/files/en-us/web/css/angle/index.md: 49: MD045/no-alt-text Images should have alternate text (alt text)␊
test-repos/mdn-content/files/en-us/web/css/angle/index.md: 60: MD045/no-alt-text Images should have alternate text (alt text)␊
test-repos/mdn-content/files/en-us/web/css/angle/index.md: 71: MD045/no-alt-text Images should have alternate text (alt text)␊
test-repos/mdn-content/files/en-us/web/css/transform-function/rotate3d/index.md: 67: MD045/no-alt-text Images should have alternate text (alt text)␊
test-repos/mdn-content/files/en-us/web/css/transform-function/rotate3d/index.md: 251: MD045/no-alt-text Images should have alternate text (alt text)␊
test-repos/mdn-content/files/en-us/web/svg/attribute/d/index.md: 234: MD007/ul-indent Unordered list indentation [Expected: 0; Actual: 10]␊
DavidAnson marked this conversation as resolved.
Show resolved Hide resolved
test-repos/mdn-content/files/en-us/web/svg/attribute/d/index.md: 556: MD007/ul-indent Unordered list indentation [Expected: 0; Actual: 12]␊
test-repos/mdn-content/files/en-us/web/svg/attribute/d/index.md: 769: MD007/ul-indent Unordered list indentation [Expected: 0; Actual: 12]␊
test-repos/mdn-content/files/en-us/web/svg/attribute/d/index.md: 838: MD007/ul-indent Unordered list indentation [Expected: 0; Actual: 12]`
Expand All @@ -58,6 +64,7 @@ Generated by [AVA](https://avajs.dev).
test-repos/mochajs-mocha/MAINTAINERS.md: 34: MD051/link-fragments Link fragments should be valid [Context: "[Projects](#projects)"]␊
test-repos/mochajs-mocha/PROJECT_CHARTER.md: 51: MD051/link-fragments Link fragments should be valid [Context: "[§2: Scope](#%c2%a72-scope)"]␊
test-repos/mochajs-mocha/PROJECT_CHARTER.md: 56: MD051/link-fragments Link fragments should be valid [Context: "[§2: Scope](#%c2%a72-scope)"]␊
test-repos/mochajs-mocha/README.md: 36: MD045/no-alt-text Images should have alternate text (alt text)␊
test-repos/mochajs-mocha/docs/index.md: 32: MD051/link-fragments Link fragments should be valid [Context: "[global variable leak detection](#-check-leaks)"]␊
test-repos/mochajs-mocha/docs/index.md: 33: MD051/link-fragments Link fragments should be valid [Context: "[optionally run tests that match a regexp](#-grep-regexp-g-regexp)"]␊
test-repos/mochajs-mocha/docs/index.md: 34: MD051/link-fragments Link fragments should be valid [Context: "[auto-exit to prevent "hanging" with an active loop](#-exit)"]␊
Expand Down Expand Up @@ -205,4 +212,4 @@ Generated by [AVA](https://avajs.dev).

> Expected linting violations

''
'test-repos/webpack-webpack-js-org/README.md: 3: MD045/no-alt-text Images should have alternate text (alt text)'
Binary file modified test/snapshots/markdownlint-test-repos.js.snap
Binary file not shown.
Loading