mirror of
https://github.com/DavidAnson/markdownlint.git
synced 2025-12-17 06:20:12 +01:00
Update MD037/no-space-in-emphasis to ignore content of math blocks when used with markdown-it-texmath (fixes #357).
This commit is contained in:
parent
d6cd840e7d
commit
df4aa9f4e8
5 changed files with 89 additions and 37 deletions
|
|
@ -228,44 +228,59 @@ function filterTokens(params, type, handler) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
module.exports.filterTokens = filterTokens;
|
module.exports.filterTokens = filterTokens;
|
||||||
|
/**
|
||||||
|
* Returns whether a token is a math block (created by markdown-it-texmath).
|
||||||
|
*
|
||||||
|
* @param {Object} token MarkdownItToken instance.
|
||||||
|
* @returns {boolean} True iff token is a math block.
|
||||||
|
*/
|
||||||
|
function isMathBlock(token) {
|
||||||
|
return ((token.tag === "math") &&
|
||||||
|
token.type.startsWith("math_block") &&
|
||||||
|
!token.type.endsWith("_end"));
|
||||||
|
}
|
||||||
// Get line metadata array
|
// Get line metadata array
|
||||||
module.exports.getLineMetadata = function getLineMetadata(params) {
|
module.exports.getLineMetadata = function getLineMetadata(params) {
|
||||||
var lineMetadata = params.lines.map(function mapLine(line, index) {
|
var lineMetadata = params.lines.map(function (line, index) { return [line, index, false, 0, false, false, false, false]; });
|
||||||
return [line, index, false, 0, false, false];
|
filterTokens(params, "fence", function (token) {
|
||||||
});
|
|
||||||
filterTokens(params, "fence", function forToken(token) {
|
|
||||||
lineMetadata[token.map[0]][3] = 1;
|
lineMetadata[token.map[0]][3] = 1;
|
||||||
lineMetadata[token.map[1] - 1][3] = -1;
|
lineMetadata[token.map[1] - 1][3] = -1;
|
||||||
for (var i = token.map[0] + 1; i < token.map[1] - 1; i++) {
|
for (var i = token.map[0] + 1; i < token.map[1] - 1; i++) {
|
||||||
lineMetadata[i][2] = true;
|
lineMetadata[i][2] = true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
filterTokens(params, "code_block", function forToken(token) {
|
filterTokens(params, "code_block", function (token) {
|
||||||
for (var i = token.map[0]; i < token.map[1]; i++) {
|
for (var i = token.map[0]; i < token.map[1]; i++) {
|
||||||
lineMetadata[i][2] = true;
|
lineMetadata[i][2] = true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
filterTokens(params, "table_open", function forToken(token) {
|
filterTokens(params, "table_open", function (token) {
|
||||||
for (var i = token.map[0]; i < token.map[1]; i++) {
|
for (var i = token.map[0]; i < token.map[1]; i++) {
|
||||||
lineMetadata[i][4] = true;
|
lineMetadata[i][4] = true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
filterTokens(params, "list_item_open", function forToken(token) {
|
filterTokens(params, "list_item_open", function (token) {
|
||||||
var count = 1;
|
var count = 1;
|
||||||
for (var i = token.map[0]; i < token.map[1]; i++) {
|
for (var i = token.map[0]; i < token.map[1]; i++) {
|
||||||
lineMetadata[i][5] = count;
|
lineMetadata[i][5] = count;
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
filterTokens(params, "hr", function forToken(token) {
|
filterTokens(params, "hr", function (token) {
|
||||||
lineMetadata[token.map[0]][6] = true;
|
lineMetadata[token.map[0]][6] = true;
|
||||||
});
|
});
|
||||||
|
params.tokens.filter(isMathBlock).forEach(function (token) {
|
||||||
|
for (var i = token.map[0]; i < token.map[1]; i++) {
|
||||||
|
lineMetadata[i][7] = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
return lineMetadata;
|
return lineMetadata;
|
||||||
};
|
};
|
||||||
// Calls the provided function for each line (with context)
|
// Calls the provided function for each line (with context)
|
||||||
module.exports.forEachLine = function forEachLine(lineMetadata, handler) {
|
module.exports.forEachLine = function forEachLine(lineMetadata, handler) {
|
||||||
lineMetadata.forEach(function forMetadata(metadata) {
|
lineMetadata.forEach(function forMetadata(metadata) {
|
||||||
// Parameters: line, lineIndex, inCode, onFence, inTable, inItem, inBreak
|
// Parameters:
|
||||||
|
// line, lineIndex, inCode, onFence, inTable, inItem, inBreak, inMath
|
||||||
handler.apply(void 0, metadata);
|
handler.apply(void 0, metadata);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
@ -277,11 +292,9 @@ module.exports.flattenLists = function flattenLists(params) {
|
||||||
var nesting = 0;
|
var nesting = 0;
|
||||||
var nestingStack = [];
|
var nestingStack = [];
|
||||||
var lastWithMap = { "map": [0, 1] };
|
var lastWithMap = { "map": [0, 1] };
|
||||||
params.tokens.forEach(function forToken(token) {
|
params.tokens.forEach(function (token) {
|
||||||
if ((token.type === "math_block") &&
|
if (isMathBlock(token) && token.map[1]) {
|
||||||
(token.tag === "math") &&
|
// markdown-it-texmath plugin does not account for math_block_end
|
||||||
token.map[1]) {
|
|
||||||
// markdown-it-texmath package does not account for math_block_end
|
|
||||||
token.map[1]++;
|
token.map[1]++;
|
||||||
}
|
}
|
||||||
if ((token.type === "bullet_list_open") ||
|
if ((token.type === "bullet_list_open") ||
|
||||||
|
|
@ -3269,13 +3282,13 @@ module.exports = {
|
||||||
// Initialize
|
// Initialize
|
||||||
var ignoreMarkersByLine = emphasisMarkersInContent(params);
|
var ignoreMarkersByLine = emphasisMarkersInContent(params);
|
||||||
resetRunTracking();
|
resetRunTracking();
|
||||||
forEachLine(lineMetadata(), function (line, lineIndex, inCode, onFence, inTable, inItem, onBreak) {
|
forEachLine(lineMetadata(), function (line, lineIndex, inCode, onFence, inTable, inItem, onBreak, inMath) {
|
||||||
var onItemStart = (inItem === 1);
|
var onItemStart = (inItem === 1);
|
||||||
if (inCode || inTable || onBreak || onItemStart || isBlankLine(line)) {
|
if (inCode || inTable || onBreak || onItemStart || isBlankLine(line)) {
|
||||||
// Emphasis resets when leaving a block
|
// Emphasis resets when leaving a block
|
||||||
resetRunTracking();
|
resetRunTracking();
|
||||||
}
|
}
|
||||||
if (inCode || onBreak) {
|
if (inCode || onBreak || inMath) {
|
||||||
// Emphasis has no meaning here
|
// Emphasis has no meaning here
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -223,45 +223,65 @@ function filterTokens(params, type, handler) {
|
||||||
}
|
}
|
||||||
module.exports.filterTokens = filterTokens;
|
module.exports.filterTokens = filterTokens;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether a token is a math block (created by markdown-it-texmath).
|
||||||
|
*
|
||||||
|
* @param {Object} token MarkdownItToken instance.
|
||||||
|
* @returns {boolean} True iff token is a math block.
|
||||||
|
*/
|
||||||
|
function isMathBlock(token) {
|
||||||
|
return (
|
||||||
|
(token.tag === "math") &&
|
||||||
|
token.type.startsWith("math_block") &&
|
||||||
|
!token.type.endsWith("_end")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// Get line metadata array
|
// Get line metadata array
|
||||||
module.exports.getLineMetadata = function getLineMetadata(params) {
|
module.exports.getLineMetadata = function getLineMetadata(params) {
|
||||||
const lineMetadata = params.lines.map(function mapLine(line, index) {
|
const lineMetadata = params.lines.map(
|
||||||
return [ line, index, false, 0, false, false ];
|
(line, index) => [ line, index, false, 0, false, false, false, false ]
|
||||||
});
|
);
|
||||||
filterTokens(params, "fence", function forToken(token) {
|
filterTokens(params, "fence", (token) => {
|
||||||
lineMetadata[token.map[0]][3] = 1;
|
lineMetadata[token.map[0]][3] = 1;
|
||||||
lineMetadata[token.map[1] - 1][3] = -1;
|
lineMetadata[token.map[1] - 1][3] = -1;
|
||||||
for (let i = token.map[0] + 1; i < token.map[1] - 1; i++) {
|
for (let i = token.map[0] + 1; i < token.map[1] - 1; i++) {
|
||||||
lineMetadata[i][2] = true;
|
lineMetadata[i][2] = true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
filterTokens(params, "code_block", function forToken(token) {
|
filterTokens(params, "code_block", (token) => {
|
||||||
for (let i = token.map[0]; i < token.map[1]; i++) {
|
for (let i = token.map[0]; i < token.map[1]; i++) {
|
||||||
lineMetadata[i][2] = true;
|
lineMetadata[i][2] = true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
filterTokens(params, "table_open", function forToken(token) {
|
filterTokens(params, "table_open", (token) => {
|
||||||
for (let i = token.map[0]; i < token.map[1]; i++) {
|
for (let i = token.map[0]; i < token.map[1]; i++) {
|
||||||
lineMetadata[i][4] = true;
|
lineMetadata[i][4] = true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
filterTokens(params, "list_item_open", function forToken(token) {
|
filterTokens(params, "list_item_open", (token) => {
|
||||||
let count = 1;
|
let count = 1;
|
||||||
for (let i = token.map[0]; i < token.map[1]; i++) {
|
for (let i = token.map[0]; i < token.map[1]; i++) {
|
||||||
lineMetadata[i][5] = count;
|
lineMetadata[i][5] = count;
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
filterTokens(params, "hr", function forToken(token) {
|
filterTokens(params, "hr", (token) => {
|
||||||
lineMetadata[token.map[0]][6] = true;
|
lineMetadata[token.map[0]][6] = true;
|
||||||
});
|
});
|
||||||
|
params.tokens.filter(isMathBlock).forEach((token) => {
|
||||||
|
for (let i = token.map[0]; i < token.map[1]; i++) {
|
||||||
|
lineMetadata[i][7] = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
return lineMetadata;
|
return lineMetadata;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Calls the provided function for each line (with context)
|
// Calls the provided function for each line (with context)
|
||||||
module.exports.forEachLine = function forEachLine(lineMetadata, handler) {
|
module.exports.forEachLine = function forEachLine(lineMetadata, handler) {
|
||||||
lineMetadata.forEach(function forMetadata(metadata) {
|
lineMetadata.forEach(function forMetadata(metadata) {
|
||||||
// Parameters: line, lineIndex, inCode, onFence, inTable, inItem, inBreak
|
// Parameters:
|
||||||
|
// line, lineIndex, inCode, onFence, inTable, inItem, inBreak, inMath
|
||||||
handler(...metadata);
|
handler(...metadata);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
@ -274,13 +294,9 @@ module.exports.flattenLists = function flattenLists(params) {
|
||||||
let nesting = 0;
|
let nesting = 0;
|
||||||
const nestingStack = [];
|
const nestingStack = [];
|
||||||
let lastWithMap = { "map": [ 0, 1 ] };
|
let lastWithMap = { "map": [ 0, 1 ] };
|
||||||
params.tokens.forEach(function forToken(token) {
|
params.tokens.forEach((token) => {
|
||||||
if (
|
if (isMathBlock(token) && token.map[1]) {
|
||||||
(token.type === "math_block") &&
|
// markdown-it-texmath plugin does not account for math_block_end
|
||||||
(token.tag === "math") &&
|
|
||||||
token.map[1]
|
|
||||||
) {
|
|
||||||
// markdown-it-texmath package does not account for math_block_end
|
|
||||||
token.map[1]++;
|
token.map[1]++;
|
||||||
}
|
}
|
||||||
if ((token.type === "bullet_list_open") ||
|
if ((token.type === "bullet_list_open") ||
|
||||||
|
|
|
||||||
|
|
@ -76,13 +76,13 @@ module.exports = {
|
||||||
resetRunTracking();
|
resetRunTracking();
|
||||||
forEachLine(
|
forEachLine(
|
||||||
lineMetadata(),
|
lineMetadata(),
|
||||||
(line, lineIndex, inCode, onFence, inTable, inItem, onBreak) => {
|
(line, lineIndex, inCode, onFence, inTable, inItem, onBreak, inMath) => {
|
||||||
const onItemStart = (inItem === 1);
|
const onItemStart = (inItem === 1);
|
||||||
if (inCode || inTable || onBreak || onItemStart || isBlankLine(line)) {
|
if (inCode || inTable || onBreak || onItemStart || isBlankLine(line)) {
|
||||||
// Emphasis resets when leaving a block
|
// Emphasis resets when leaving a block
|
||||||
resetRunTracking();
|
resetRunTracking();
|
||||||
}
|
}
|
||||||
if (inCode || onBreak) {
|
if (inCode || onBreak || inMath) {
|
||||||
// Emphasis has no meaning here
|
// Emphasis has no meaning here
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1508,15 +1508,19 @@ $$\n`
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
test.cb("texmath-content-in-lists with texmath plugin", (t) => {
|
test.cb("texmath test files with texmath plugin", (t) => {
|
||||||
t.plan(2);
|
t.plan(2);
|
||||||
markdownlint({
|
markdownlint({
|
||||||
"files": [ "./test/texmath-content-in-lists.md" ],
|
"files": [
|
||||||
|
"./test/texmath-content-in-lists.md",
|
||||||
|
"./test/texmath-content-violating-md037.md"
|
||||||
|
],
|
||||||
"markdownItPlugins": [ [ pluginTexMath, pluginTexMathOptions ] ]
|
"markdownItPlugins": [ [ pluginTexMath, pluginTexMathOptions ] ]
|
||||||
}, function callback(err, actual) {
|
}, function callback(err, actual) {
|
||||||
t.falsy(err);
|
t.falsy(err);
|
||||||
const expected = {
|
const expected = {
|
||||||
"./test/texmath-content-in-lists.md": []
|
"./test/texmath-content-in-lists.md": [],
|
||||||
|
"./test/texmath-content-violating-md037.md": []
|
||||||
};
|
};
|
||||||
t.deepEqual(actual, expected, "Unexpected issues.");
|
t.deepEqual(actual, expected, "Unexpected issues.");
|
||||||
t.end();
|
t.end();
|
||||||
|
|
|
||||||
19
test/texmath-content-violating-md037.md
Normal file
19
test/texmath-content-violating-md037.md
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
# texmath-content-violating-md037
|
||||||
|
|
||||||
|
## Inline (not handled)
|
||||||
|
|
||||||
|
text `$ x * y * z $` text
|
||||||
|
|
||||||
|
text `$$ x * y * z $$` text
|
||||||
|
|
||||||
|
## Block (handled when used with markdown-it-texmath)
|
||||||
|
|
||||||
|
$$
|
||||||
|
x * y * z {MD037}
|
||||||
|
$$
|
||||||
|
|
||||||
|
text
|
||||||
|
|
||||||
|
$$
|
||||||
|
x * y = x * y {MD037}
|
||||||
|
$$
|
||||||
Loading…
Add table
Add a link
Reference in a new issue