mirror of
https://github.com/DavidAnson/markdownlint.git
synced 2025-12-16 22:10:13 +01:00
Update MD060/table-column-style to add aligned_delimiter parameter (fixes #1854).
This commit is contained in:
parent
8e974f95d5
commit
f6c5369ef4
14 changed files with 648 additions and 32 deletions
8
lib/configuration-strict.d.ts
vendored
8
lib/configuration-strict.d.ts
vendored
|
|
@ -2281,6 +2281,10 @@ export interface ConfigurationStrict {
|
|||
* Table column style
|
||||
*/
|
||||
style?: "any" | "aligned" | "compact" | "tight";
|
||||
/**
|
||||
* Aligned delimiter columns
|
||||
*/
|
||||
aligned_delimiter?: boolean;
|
||||
};
|
||||
/**
|
||||
* MD060/table-column-style : Table column style : https://github.com/DavidAnson/markdownlint/blob/v0.39.0/doc/md060.md
|
||||
|
|
@ -2301,6 +2305,10 @@ export interface ConfigurationStrict {
|
|||
* Table column style
|
||||
*/
|
||||
style?: "any" | "aligned" | "compact" | "tight";
|
||||
/**
|
||||
* Aligned delimiter columns
|
||||
*/
|
||||
aligned_delimiter?: boolean;
|
||||
};
|
||||
/**
|
||||
* headings : MD001, MD003, MD018, MD019, MD020, MD021, MD022, MD023, MD024, MD025, MD026, MD036, MD041, MD043
|
||||
|
|
|
|||
|
|
@ -8,6 +8,22 @@ import stringWidth from "string-width";
|
|||
/** @typedef {import("markdownlint").MicromarkToken} MicromarkToken */
|
||||
/** @typedef {import("markdownlint").RuleOnErrorInfo} RuleOnErrorInfo */
|
||||
|
||||
/**
|
||||
* Adds a RuleOnErrorInfo object to a list of RuleOnErrorInfo objects.
|
||||
*
|
||||
* @param {RuleOnErrorInfo[]} errors List of errors.
|
||||
* @param {number} lineNumber Line number.
|
||||
* @param {number} column Column number.
|
||||
* @param {string} detail Detail message.
|
||||
*/
|
||||
function addError(errors, lineNumber, column, detail) {
|
||||
errors.push({
|
||||
lineNumber,
|
||||
detail,
|
||||
"range": [ column, 1 ]
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef Column
|
||||
* @property {number} actual Actual column (1-based).
|
||||
|
|
@ -34,19 +50,28 @@ function getTableDividerColumns(lines, row) {
|
|||
}
|
||||
|
||||
/**
|
||||
* Adds a RuleOnErrorInfo object to a list of RuleOnErrorInfo objects.
|
||||
* Checks the specified table rows for consistency with the "aligned" style.
|
||||
*
|
||||
* @param {RuleOnErrorInfo[]} errors List of errors.
|
||||
* @param {number} lineNumber Line number.
|
||||
* @param {number} column Column number.
|
||||
* @param {readonly string[]} lines File/string lines.
|
||||
* @param {MicromarkToken[]} rows Micromark row tokens.
|
||||
* @param {string} detail Detail message.
|
||||
* @returns {RuleOnErrorInfo[]} List of errors.
|
||||
*/
|
||||
function addError(errors, lineNumber, column, detail) {
|
||||
errors.push({
|
||||
lineNumber,
|
||||
detail,
|
||||
"range": [ column, 1 ]
|
||||
});
|
||||
function checkStyleAligned(lines, rows, detail) {
|
||||
/** @type {RuleOnErrorInfo[]} */
|
||||
const errorInfos = [];
|
||||
const headingRow = rows[0];
|
||||
const headingDividerColumns = getTableDividerColumns(lines, headingRow);
|
||||
for (const row of rows.slice(1)) {
|
||||
const remainingHeadingDividerColumns = new Set(headingDividerColumns.map((column) => column.effective));
|
||||
const rowDividerColumns = getTableDividerColumns(lines, row);
|
||||
for (const dividerColumn of rowDividerColumns) {
|
||||
if ((remainingHeadingDividerColumns.size > 0) && !remainingHeadingDividerColumns.delete(dividerColumn.effective)) {
|
||||
addError(errorInfos, row.startLine, dividerColumn.actual, detail);
|
||||
}
|
||||
}
|
||||
}
|
||||
return errorInfos;
|
||||
}
|
||||
|
||||
/** @type {import("markdownlint").Rule} */
|
||||
|
|
@ -60,27 +85,19 @@ export default {
|
|||
const styleAlignedAllowed = (style === "any") || (style === "aligned");
|
||||
const styleCompactAllowed = (style === "any") || (style === "compact");
|
||||
const styleTightAllowed = (style === "any") || (style === "tight");
|
||||
const alignedDelimiter = !!params.config.aligned_delimiter;
|
||||
const lines = params.lines;
|
||||
|
||||
// Scan all tables/rows
|
||||
const tables = filterByTypesCached([ "table" ]);
|
||||
for (const table of tables) {
|
||||
const rows = filterByTypes(table.children, [ "tableDelimiterRow", "tableRow" ]);
|
||||
const headingRow = rows[0];
|
||||
|
||||
// Determine errors for style "aligned"
|
||||
/** @type {RuleOnErrorInfo[]} */
|
||||
const errorsIfAligned = [];
|
||||
if (styleAlignedAllowed) {
|
||||
const headingDividerColumns = getTableDividerColumns(params.lines, headingRow);
|
||||
for (const row of rows.slice(1)) {
|
||||
const remainingHeadingDividerColumns = new Set(headingDividerColumns.map((column) => column.effective));
|
||||
const rowDividerColumns = getTableDividerColumns(params.lines, row);
|
||||
for (const dividerColumn of rowDividerColumns) {
|
||||
if ((remainingHeadingDividerColumns.size > 0) && !remainingHeadingDividerColumns.delete(dividerColumn.effective)) {
|
||||
addError(errorsIfAligned, row.startLine, dividerColumn.actual, "Table pipe does not align with heading for style \"aligned\"");
|
||||
}
|
||||
}
|
||||
}
|
||||
errorsIfAligned.push(...checkStyleAligned(lines, rows, "Table pipe does not align with heading for style \"aligned\""));
|
||||
}
|
||||
|
||||
// Determine errors for styles "compact" and "tight"
|
||||
|
|
@ -92,6 +109,11 @@ export default {
|
|||
(styleCompactAllowed || styleTightAllowed) &&
|
||||
!(styleAlignedAllowed && (errorsIfAligned.length === 0))
|
||||
) {
|
||||
if (alignedDelimiter) {
|
||||
const errorInfos = checkStyleAligned(lines, rows.slice(0, 2), "Table pipe does not align with heading for option \"aligned_delimiter\"");
|
||||
errorsIfCompact.push(...errorInfos);
|
||||
errorsIfTight.push(...errorInfos);
|
||||
}
|
||||
for (const row of rows) {
|
||||
const tokensOfInterest = filterByTypes(row.children, [ "tableCellDivider", "tableContent", "whitespace" ]);
|
||||
for (let i = 0; i < tokensOfInterest.length; i++) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue