2018-01-21 21:44:25 -08:00
|
|
|
// @ts-check
|
|
|
|
|
|
|
|
"use strict";
|
|
|
|
|
2023-02-23 22:20:27 -08:00
|
|
|
const { addErrorContext } = require("../helpers");
|
2024-06-09 17:09:03 -07:00
|
|
|
const { filterByTypes, tokenIfType } = require("../helpers/micromark.cjs");
|
2018-01-21 21:44:25 -08:00
|
|
|
|
2022-12-19 21:51:18 -08:00
|
|
|
const leftSpaceRe = /^\s(?:[^`]|$)/;
|
2019-09-06 22:35:33 -07:00
|
|
|
const rightSpaceRe = /[^`]\s$/;
|
2023-02-23 22:20:27 -08:00
|
|
|
const trimCodeText = (text, start, end) => {
|
|
|
|
text = text.replace(/^\s+$/, "");
|
|
|
|
if (start) {
|
|
|
|
text = text.replace(/^\s+?(\s`|\S)/, "$1");
|
|
|
|
}
|
|
|
|
if (end) {
|
|
|
|
text = text.replace(/(`\s|\S)\s+$/, "$1");
|
|
|
|
}
|
|
|
|
return text;
|
|
|
|
};
|
2018-01-21 21:44:25 -08:00
|
|
|
|
2024-02-27 20:42:09 -08:00
|
|
|
// eslint-disable-next-line jsdoc/valid-types
|
|
|
|
/** @type import("./markdownlint").Rule */
|
2018-01-21 21:44:25 -08:00
|
|
|
module.exports = {
|
|
|
|
"names": [ "MD038", "no-space-in-code" ],
|
|
|
|
"description": "Spaces inside code span elements",
|
|
|
|
"tags": [ "whitespace", "code" ],
|
2024-03-09 16:17:50 -08:00
|
|
|
"parser": "micromark",
|
2018-01-21 21:44:25 -08:00
|
|
|
"function": function MD038(params, onError) {
|
2024-06-21 21:03:30 -07:00
|
|
|
const codeTexts = filterByTypes(
|
|
|
|
params.parsers.micromark.tokens,
|
|
|
|
[ "codeText" ]
|
|
|
|
);
|
2023-10-21 22:03:11 -07:00
|
|
|
for (const codeText of codeTexts) {
|
|
|
|
const { children } = codeText;
|
2023-02-23 22:20:27 -08:00
|
|
|
const first = 0;
|
2023-02-25 15:42:28 -08:00
|
|
|
const last = children.length - 1;
|
|
|
|
const startSequence = tokenIfType(children[first], "codeTextSequence");
|
|
|
|
const endSequence = tokenIfType(children[last], "codeTextSequence");
|
2023-02-23 22:20:27 -08:00
|
|
|
const startData =
|
2023-02-25 15:42:28 -08:00
|
|
|
tokenIfType(children[first + 1], "codeTextData") ||
|
|
|
|
tokenIfType(children[first + 2], "codeTextData");
|
2023-02-23 22:20:27 -08:00
|
|
|
const endData =
|
2023-02-25 15:42:28 -08:00
|
|
|
tokenIfType(children[last - 1], "codeTextData") ||
|
|
|
|
tokenIfType(children[last - 2], "codeTextData");
|
2023-02-23 22:20:27 -08:00
|
|
|
if (startSequence && endSequence && startData && endData) {
|
|
|
|
const spaceLeft = leftSpaceRe.test(startData.text);
|
2023-12-06 21:22:29 -08:00
|
|
|
const spaceRight = rightSpaceRe.test(endData.text);
|
2023-02-23 22:20:27 -08:00
|
|
|
if (spaceLeft || spaceRight) {
|
|
|
|
let lineNumber = startSequence.startLine;
|
|
|
|
let range = null;
|
|
|
|
let fixInfo = null;
|
|
|
|
if (startSequence.startLine === endSequence.endLine) {
|
|
|
|
range = [
|
|
|
|
startSequence.startColumn,
|
|
|
|
endSequence.endColumn - startSequence.startColumn
|
|
|
|
];
|
|
|
|
fixInfo = {
|
|
|
|
"editColumn": startSequence.endColumn,
|
|
|
|
"deleteCount": endSequence.startColumn - startSequence.endColumn,
|
|
|
|
"insertText": trimCodeText(startData.text, true, true)
|
|
|
|
};
|
2023-12-06 21:22:29 -08:00
|
|
|
} else if (spaceLeft && (startSequence.endLine === startData.startLine)) {
|
2023-02-23 22:20:27 -08:00
|
|
|
range = [
|
|
|
|
startSequence.startColumn,
|
|
|
|
startData.endColumn - startSequence.startColumn
|
|
|
|
];
|
|
|
|
fixInfo = {
|
|
|
|
"editColumn": startSequence.endColumn,
|
|
|
|
"deleteCount": startData.endColumn - startData.startColumn,
|
|
|
|
"insertText": trimCodeText(startData.text, true, false)
|
|
|
|
};
|
2023-12-06 21:22:29 -08:00
|
|
|
} else if (spaceRight && (endData.text.trim().length > 0)) {
|
2023-02-23 22:20:27 -08:00
|
|
|
lineNumber = endSequence.endLine;
|
|
|
|
range = [
|
|
|
|
endData.startColumn,
|
|
|
|
endSequence.endColumn - endData.startColumn
|
|
|
|
];
|
|
|
|
fixInfo = {
|
|
|
|
"editColumn": endData.startColumn,
|
|
|
|
"deleteCount": endData.endColumn - endData.startColumn,
|
|
|
|
"insertText": trimCodeText(endData.text, false, true)
|
|
|
|
};
|
|
|
|
}
|
2023-12-06 21:22:29 -08:00
|
|
|
if (range) {
|
|
|
|
const context = params
|
|
|
|
.lines[lineNumber - 1]
|
|
|
|
.substring(range[0] - 1, range[0] - 1 + range[1]);
|
|
|
|
addErrorContext(
|
|
|
|
onError,
|
|
|
|
lineNumber,
|
|
|
|
context,
|
|
|
|
spaceLeft,
|
|
|
|
spaceRight,
|
|
|
|
range,
|
|
|
|
fixInfo
|
|
|
|
);
|
|
|
|
}
|
2023-02-23 22:20:27 -08:00
|
|
|
}
|
2019-01-30 22:09:20 -08:00
|
|
|
}
|
2023-02-23 22:20:27 -08:00
|
|
|
}
|
2018-01-21 21:44:25 -08:00
|
|
|
}
|
|
|
|
};
|