2018-01-21 21:44:25 -08:00
|
|
|
// @ts-check
|
|
|
|
|
2025-02-13 22:07:27 -08:00
|
|
|
import { addErrorContext } from "../helpers/helpers.cjs";
|
2024-11-28 20:36:44 -08:00
|
|
|
import { getDescendantsByType } from "../helpers/micromark-helpers.cjs";
|
|
|
|
import { filterByTypesCached } from "./cache.mjs";
|
2018-01-21 21:44:25 -08:00
|
|
|
|
2024-12-03 19:58:28 -08:00
|
|
|
/** @type {import("markdownlint").Rule} */
|
2024-11-28 20:36:44 -08:00
|
|
|
export default {
|
2018-01-21 21:44:25 -08:00
|
|
|
"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-08-24 22:05:16 -07:00
|
|
|
const codeTexts = filterByTypesCached([ "codeText" ]);
|
2023-10-21 22:03:11 -07:00
|
|
|
for (const codeText of codeTexts) {
|
2024-09-16 20:50:54 -07:00
|
|
|
const datas = getDescendantsByType(codeText, [ "codeTextData" ]);
|
2025-02-07 20:03:30 -08:00
|
|
|
if (datas.length > 0) {
|
|
|
|
const paddings = getDescendantsByType(codeText, [ "codeTextPadding" ]);
|
|
|
|
// Check for extra space at start of code
|
|
|
|
const startPadding = paddings[0];
|
|
|
|
const startData = datas[0];
|
|
|
|
const startMatch = /^(\s+)(\S)/.exec(startData.text) || [ null, "", "" ];
|
|
|
|
const startBacktick = (startMatch[2] === "`");
|
|
|
|
const startCount = startMatch[1].length - ((startBacktick && !startPadding) ? 1 : 0);
|
|
|
|
const startSpaces = startCount > 0;
|
|
|
|
// Check for extra space at end of code
|
|
|
|
const endPadding = paddings[paddings.length - 1];
|
|
|
|
const endData = datas[datas.length - 1];
|
|
|
|
const endMatch = /(\S)(\s+)$/.exec(endData.text) || [ null, "", "" ];
|
|
|
|
const endBacktick = (endMatch[1] === "`");
|
|
|
|
const endCount = endMatch[2].length - ((endBacktick && !endPadding) ? 1 : 0);
|
|
|
|
const endSpaces = endCount > 0;
|
|
|
|
// Check if safe to remove 1-space padding
|
|
|
|
const removePadding = startSpaces && endSpaces && startPadding && endPadding && !startBacktick && !endBacktick;
|
2025-02-13 22:07:27 -08:00
|
|
|
const context = codeText.text;
|
2025-02-07 20:03:30 -08:00
|
|
|
// If extra space at start, report violation
|
|
|
|
if (startSpaces) {
|
|
|
|
const startColumn = (removePadding ? startPadding : startData).startColumn;
|
|
|
|
const length = startCount + (removePadding ? startPadding.text.length : 0);
|
|
|
|
addErrorContext(
|
|
|
|
onError,
|
|
|
|
startData.startLine,
|
|
|
|
context,
|
|
|
|
true,
|
|
|
|
false,
|
|
|
|
[ startColumn, length ],
|
|
|
|
{
|
|
|
|
"editColumn": startColumn,
|
|
|
|
"deleteCount": length
|
|
|
|
}
|
|
|
|
);
|
|
|
|
}
|
|
|
|
// If extra space at end, report violation
|
|
|
|
if (endSpaces) {
|
|
|
|
const endColumn = (removePadding ? endPadding : endData).endColumn;
|
|
|
|
const length = endCount + (removePadding ? endPadding.text.length : 0);
|
|
|
|
addErrorContext(
|
|
|
|
onError,
|
|
|
|
endData.endLine,
|
|
|
|
context,
|
|
|
|
false,
|
|
|
|
true,
|
|
|
|
[ endColumn - length, length ],
|
|
|
|
{
|
|
|
|
"editColumn": endColumn - length,
|
|
|
|
"deleteCount": length
|
|
|
|
}
|
|
|
|
);
|
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
|
|
|
}
|
|
|
|
};
|