markdownlint/lib/md059.mjs

60 lines
1.6 KiB
JavaScript

// @ts-check
import { addErrorContext } from "../helpers/helpers.cjs";
import { filterByTypesCached } from "./cache.mjs";
const defaultBannedText = [
"click here",
"here",
"learn more",
"link",
"more",
"read more"
];
/**
* Normalizes a string and removes extra whitespaces and punctuations.
*
* @param {string} text String to transform.
* @returns {string} Normalized string with no punctuations or extra whitespaces.
*/
function normalizeText(text) {
return text
.toLowerCase()
.replace(/\W+/g, " ")
.replace(/\s+/g, " ")
.trim();
}
/** @type {import("markdownlint").Rule} */
export default {
"names": [ "MD059", "descriptive-link-text" ],
"description": "Link text should be descriptive",
"tags": [ "links", "accessibility" ],
"parser": "micromark",
"function": function MD059(params, onError) {
const bannedNames = new Set(params.config.link_texts || defaultBannedText);
const labels = filterByTypesCached([ "label" ])
.filter((label) => label.parent?.type === "link");
for (const label of labels) {
const labelTexts = label.children.filter((child) => child.type === "labelText");
for (const labelText of labelTexts) {
const { text } = label;
if (bannedNames.has(normalizeText(text))) {
const range = labelText.startLine === labelText.endLine ?
[ labelText.startColumn, text.length ] :
undefined;
addErrorContext(
onError,
labelText.startLine,
text,
undefined,
undefined,
range
);
}
}
}
}
};