// @ts-check "use strict"; const { addErrorContext } = require("../helpers"); const { addRangeToSet, filterByTypes } = require("../helpers/micromark.cjs"); // eslint-disable-next-line jsdoc/valid-types /** @type import("./markdownlint").Rule */ module.exports = { "names": [ "MD020", "no-missing-space-closed-atx" ], "description": "No space inside hashes on closed atx style heading", "tags": [ "headings", "atx_closed", "spaces" ], "parser": "micromark", "function": function MD020(params, onError) { const { lines, parsers } = params; const ignoreBlockLineNumbers = new Set(); for (const ignoreBlock of filterByTypes(parsers.micromark.tokens, [ "codeIndented", "codeFenced", "htmlFlow" ])) { addRangeToSet(ignoreBlockLineNumbers, ignoreBlock.startLine, ignoreBlock.endLine); } for (const [ lineIndex, line ] of lines.entries()) { if (!ignoreBlockLineNumbers.has(lineIndex + 1)) { const match = /^(#+)([ \t]*)([^#]*?[^#\\])([ \t]*)((?:\\#)?)(#+)(\s*)$/.exec(line); if (match) { const [ , leftHash, { "length": leftSpaceLength }, content, { "length": rightSpaceLength }, rightEscape, rightHash, { "length": trailSpaceLength } ] = match; const leftHashLength = leftHash.length; const rightHashLength = rightHash.length; const left = !leftSpaceLength; const right = !rightSpaceLength || !!rightEscape; const rightEscapeReplacement = rightEscape ? `${rightEscape} ` : ""; if (left || right) { const range = left ? [ 1, leftHashLength + 1 ] : [ line.length - trailSpaceLength - rightHashLength, rightHashLength + 1 ]; addErrorContext( onError, lineIndex + 1, line.trim(), left, right, range, { "editColumn": 1, "deleteCount": line.length, "insertText": `${leftHash} ${content} ${rightEscapeReplacement}${rightHash}` } ); } } } } } };