mirror of
https://github.com/DavidAnson/markdownlint.git
synced 2025-12-16 22:10:13 +01:00
Promote applyFix and applyFixes helpers into core library.
This commit is contained in:
parent
e0219411c6
commit
4e30462216
13 changed files with 898 additions and 823 deletions
40
lib/markdownlint.d.ts
vendored
40
lib/markdownlint.d.ts
vendored
|
|
@ -8,7 +8,7 @@ export = markdownlint;
|
|||
*/
|
||||
declare function markdownlint(options: Options | null, callback: LintCallback): void;
|
||||
declare namespace markdownlint {
|
||||
export { markdownlintSync as sync, readConfig, readConfigSync, getVersion, promises, RuleFunction, RuleParams, MarkdownParsers, ParserMarkdownIt, ParserMicromark, MarkdownItToken, MicromarkTokenType, MicromarkToken, RuleOnError, RuleOnErrorInfo, RuleOnErrorFixInfo, Rule, Options, Plugin, ToStringCallback, LintResults, LintError, FixInfo, LintContentCallback, LintCallback, Configuration, ConfigurationStrict, RuleConfiguration, ConfigurationParser, ReadConfigCallback, ResolveConfigExtendsCallback };
|
||||
export { markdownlintSync as sync, readConfig, readConfigSync, getVersion, promises, applyFix, applyFixes, RuleFunction, RuleParams, MarkdownParsers, ParserMarkdownIt, ParserMicromark, MarkdownItToken, MicromarkTokenType, MicromarkToken, RuleOnError, RuleOnErrorInfo, RuleOnErrorFixInfo, RuleOnErrorFixInfoNormalized, Rule, Options, Plugin, ToStringCallback, LintResults, LintError, FixInfo, LintContentCallback, LintCallback, Configuration, ConfigurationStrict, RuleConfiguration, ConfigurationParser, ReadConfigCallback, ResolveConfigExtendsCallback };
|
||||
}
|
||||
/**
|
||||
* Lint specified Markdown files synchronously.
|
||||
|
|
@ -49,6 +49,23 @@ declare namespace promises {
|
|||
export { extendConfigPromise as extendConfig };
|
||||
export { readConfigPromise as readConfig };
|
||||
}
|
||||
/**
|
||||
* Applies the specified fix to a Markdown content line.
|
||||
*
|
||||
* @param {string} line Line of Markdown content.
|
||||
* @param {RuleOnErrorFixInfo} fixInfo RuleOnErrorFixInfo instance.
|
||||
* @param {string} [lineEnding] Line ending to use.
|
||||
* @returns {string | null} Fixed content or null if deleted.
|
||||
*/
|
||||
declare function applyFix(line: string, fixInfo: RuleOnErrorFixInfo, lineEnding?: string): string | null;
|
||||
/**
|
||||
* Applies as many of the specified fixes as possible to Markdown content.
|
||||
*
|
||||
* @param {string} input Lines of Markdown content.
|
||||
* @param {RuleOnErrorInfo[]} errors RuleOnErrorInfo instances.
|
||||
* @returns {string} Fixed content.
|
||||
*/
|
||||
declare function applyFixes(input: string, errors: RuleOnErrorInfo[]): string;
|
||||
/**
|
||||
* Function to implement rule logic.
|
||||
*/
|
||||
|
|
@ -270,6 +287,27 @@ type RuleOnErrorFixInfo = {
|
|||
*/
|
||||
insertText?: string;
|
||||
};
|
||||
/**
|
||||
* RuleOnErrorInfo with all optional properties present.
|
||||
*/
|
||||
type RuleOnErrorFixInfoNormalized = {
|
||||
/**
|
||||
* Line number (1-based).
|
||||
*/
|
||||
lineNumber: number;
|
||||
/**
|
||||
* Column of the fix (1-based).
|
||||
*/
|
||||
editColumn: number;
|
||||
/**
|
||||
* Count of characters to delete.
|
||||
*/
|
||||
deleteCount: number;
|
||||
/**
|
||||
* Text to insert (after deleting).
|
||||
*/
|
||||
insertText: string;
|
||||
};
|
||||
/**
|
||||
* Rule definition.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1204,6 +1204,119 @@ function readConfigSync(file, parsers, fs) {
|
|||
return config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalizes the fields of a RuleOnErrorFixInfo instance.
|
||||
*
|
||||
* @param {RuleOnErrorFixInfo} fixInfo RuleOnErrorFixInfo instance.
|
||||
* @param {number} [lineNumber] Line number.
|
||||
* @returns {RuleOnErrorFixInfoNormalized} Normalized RuleOnErrorFixInfo instance.
|
||||
*/
|
||||
function normalizeFixInfo(fixInfo, lineNumber = 0) {
|
||||
return {
|
||||
"lineNumber": fixInfo.lineNumber || lineNumber,
|
||||
"editColumn": fixInfo.editColumn || 1,
|
||||
"deleteCount": fixInfo.deleteCount || 0,
|
||||
"insertText": fixInfo.insertText || ""
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the specified fix to a Markdown content line.
|
||||
*
|
||||
* @param {string} line Line of Markdown content.
|
||||
* @param {RuleOnErrorFixInfo} fixInfo RuleOnErrorFixInfo instance.
|
||||
* @param {string} [lineEnding] Line ending to use.
|
||||
* @returns {string | null} Fixed content or null if deleted.
|
||||
*/
|
||||
function applyFix(line, fixInfo, lineEnding = "\n") {
|
||||
const { editColumn, deleteCount, insertText } = normalizeFixInfo(fixInfo);
|
||||
const editIndex = editColumn - 1;
|
||||
return (deleteCount === -1) ?
|
||||
null :
|
||||
line.slice(0, editIndex) + insertText.replace(/\n/g, lineEnding) + line.slice(editIndex + deleteCount);
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies as many of the specified fixes as possible to Markdown content.
|
||||
*
|
||||
* @param {string} input Lines of Markdown content.
|
||||
* @param {RuleOnErrorInfo[]} errors RuleOnErrorInfo instances.
|
||||
* @returns {string} Fixed content.
|
||||
*/
|
||||
function applyFixes(input, errors) {
|
||||
const lineEnding = helpers.getPreferredLineEnding(input, require("node:os"));
|
||||
const lines = input.split(helpers.newLineRe);
|
||||
// Normalize fixInfo objects
|
||||
let fixInfos = errors
|
||||
.filter((error) => error.fixInfo)
|
||||
// @ts-ignore
|
||||
.map((error) => normalizeFixInfo(error.fixInfo, error.lineNumber));
|
||||
// Sort bottom-to-top, line-deletes last, right-to-left, long-to-short
|
||||
fixInfos.sort((a, b) => {
|
||||
const aDeletingLine = (a.deleteCount === -1);
|
||||
const bDeletingLine = (b.deleteCount === -1);
|
||||
return (
|
||||
(b.lineNumber - a.lineNumber) ||
|
||||
(aDeletingLine ? 1 : (bDeletingLine ? -1 : 0)) ||
|
||||
(b.editColumn - a.editColumn) ||
|
||||
(b.insertText.length - a.insertText.length)
|
||||
);
|
||||
});
|
||||
// Remove duplicate entries (needed for following collapse step)
|
||||
// eslint-disable-next-line jsdoc/valid-types
|
||||
/** @type RuleOnErrorFixInfo */
|
||||
let lastFixInfo = {};
|
||||
fixInfos = fixInfos.filter((fixInfo) => {
|
||||
const unique = (
|
||||
(fixInfo.lineNumber !== lastFixInfo.lineNumber) ||
|
||||
(fixInfo.editColumn !== lastFixInfo.editColumn) ||
|
||||
(fixInfo.deleteCount !== lastFixInfo.deleteCount) ||
|
||||
(fixInfo.insertText !== lastFixInfo.insertText)
|
||||
);
|
||||
lastFixInfo = fixInfo;
|
||||
return unique;
|
||||
});
|
||||
// Collapse insert/no-delete and no-insert/delete for same line/column
|
||||
lastFixInfo = {
|
||||
"lineNumber": -1
|
||||
};
|
||||
for (const fixInfo of fixInfos) {
|
||||
if (
|
||||
(fixInfo.lineNumber === lastFixInfo.lineNumber) &&
|
||||
(fixInfo.editColumn === lastFixInfo.editColumn) &&
|
||||
!fixInfo.insertText &&
|
||||
(fixInfo.deleteCount > 0) &&
|
||||
lastFixInfo.insertText &&
|
||||
!lastFixInfo.deleteCount) {
|
||||
fixInfo.insertText = lastFixInfo.insertText;
|
||||
lastFixInfo.lineNumber = 0;
|
||||
}
|
||||
lastFixInfo = fixInfo;
|
||||
}
|
||||
fixInfos = fixInfos.filter((fixInfo) => fixInfo.lineNumber);
|
||||
// Apply all (remaining/updated) fixes
|
||||
let lastLineIndex = -1;
|
||||
let lastEditIndex = -1;
|
||||
for (const fixInfo of fixInfos) {
|
||||
const { lineNumber, editColumn, deleteCount } = fixInfo;
|
||||
const lineIndex = lineNumber - 1;
|
||||
const editIndex = editColumn - 1;
|
||||
if (
|
||||
(lineIndex !== lastLineIndex) ||
|
||||
(deleteCount === -1) ||
|
||||
((editIndex + deleteCount) <=
|
||||
(lastEditIndex - ((deleteCount > 0) ? 0 : 1)))
|
||||
) {
|
||||
// @ts-ignore
|
||||
lines[lineIndex] = applyFix(lines[lineIndex], fixInfo, lineEnding);
|
||||
}
|
||||
lastLineIndex = lineIndex;
|
||||
lastEditIndex = editIndex;
|
||||
}
|
||||
// Return corrected input
|
||||
return lines.filter((line) => line !== null).join(lineEnding);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the (semantic) version of the library.
|
||||
*
|
||||
|
|
@ -1223,6 +1336,8 @@ markdownlint.promises = {
|
|||
"extendConfig": extendConfigPromise,
|
||||
"readConfig": readConfigPromise
|
||||
};
|
||||
markdownlint.applyFix = applyFix;
|
||||
markdownlint.applyFixes = applyFixes;
|
||||
module.exports = markdownlint;
|
||||
|
||||
// Type declarations
|
||||
|
|
@ -1341,6 +1456,16 @@ module.exports = markdownlint;
|
|||
* @property {string} [insertText] Text to insert (after deleting).
|
||||
*/
|
||||
|
||||
/**
|
||||
* RuleOnErrorInfo with all optional properties present.
|
||||
*
|
||||
* @typedef {Object} RuleOnErrorFixInfoNormalized
|
||||
* @property {number} lineNumber Line number (1-based).
|
||||
* @property {number} editColumn Column of the fix (1-based).
|
||||
* @property {number} deleteCount Count of characters to delete.
|
||||
* @property {string} insertText Text to insert (after deleting).
|
||||
*/
|
||||
|
||||
/**
|
||||
* Rule definition.
|
||||
*
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue