diff --git a/src/index.js b/src/index.js index 1243d00..ae30d5a 100644 --- a/src/index.js +++ b/src/index.js @@ -7,7 +7,7 @@ const { filterTokens, convertHeadingToHTMLFragment, getMarkdownHeadings, - getMarkdownAnchorHTMLFragments, + getMarkdownIdOrAnchorNameFragments, } = require("./utils.js") /** @typedef {import('markdownlint').Rule} MarkdownLintRule */ @@ -46,65 +46,83 @@ const customRule = { } } - if (hrefSrc != null) { - const url = new URL(hrefSrc, pathToFileURL(params.name)) - const isRelative = - url.protocol === "file:" && - !hrefSrc.startsWith("/") && - !hrefSrc.startsWith("#") - if (isRelative) { - const detail = `"${hrefSrc}"` + if (hrefSrc == null) { + continue + } - if (!fs.existsSync(url)) { + const url = new URL(hrefSrc, pathToFileURL(params.name)) + const isRelative = + url.protocol === "file:" && + !hrefSrc.startsWith("/") && + !hrefSrc.startsWith("#") + + if (!isRelative) { + continue + } + + const detail = `"${hrefSrc}"` + + if (!fs.existsSync(url)) { + onError({ + lineNumber, + detail: `${detail} should exist in the file system`, + }) + continue + } + + if (url.hash.length <= 0) { + if (hrefSrc.includes("#")) { + if (type !== "link_open") { onError({ lineNumber, - detail: `${detail} should exist in the file system`, + detail: `${detail} should not have a fragment identifier as it is an image`, }) continue } - if (type !== "link_open") { - continue - } - - if (url.hash.length <= 0) { - if (hrefSrc.includes("#")) { - onError({ - lineNumber, - detail: `${detail} should have a valid fragment identifier`, - }) - } - } - - if (url.hash.length > 0) { - const fileContent = fs.readFileSync(url, { encoding: "utf8" }) - const headings = getMarkdownHeadings(fileContent) - const anchorHTMLFragments = - getMarkdownAnchorHTMLFragments(fileContent) - - /** @type {Map} */ - const fragments = new Map() - - const headingsHTMLFragments = headings.map((heading) => { - const fragment = convertHeadingToHTMLFragment(heading) - const count = fragments.get(fragment) ?? 0 - fragments.set(fragment, count + 1) - if (count !== 0) { - return `${fragment}-${count}` - } - return fragment - }) - - headingsHTMLFragments.push(...anchorHTMLFragments) - - if (!headingsHTMLFragments.includes(url.hash)) { - onError({ - lineNumber, - detail: `${detail} should have a valid fragment identifier`, - }) - } - } + onError({ + lineNumber, + detail: `${detail} should have a valid fragment identifier`, + }) + continue } + continue + } + + if (type !== "link_open") { + onError({ + lineNumber, + detail: `${detail} should not have a fragment identifier as it is an image`, + }) + continue + } + + const fileContent = fs.readFileSync(url, { encoding: "utf8" }) + const headings = getMarkdownHeadings(fileContent) + const idOrAnchorNameHTMLFragments = + getMarkdownIdOrAnchorNameFragments(fileContent) + + /** @type {Map} */ + const fragments = new Map() + + const fragmentsHTML = headings.map((heading) => { + const fragment = convertHeadingToHTMLFragment(heading) + const count = fragments.get(fragment) ?? 0 + fragments.set(fragment, count + 1) + if (count !== 0) { + return `${fragment}-${count}` + } + return fragment + }) + + fragmentsHTML.push(...idOrAnchorNameHTMLFragments) + + if (!fragmentsHTML.includes(url.hash)) { + onError({ + lineNumber, + detail: `${detail} should have a valid fragment identifier`, + }) + continue } } }) diff --git a/src/utils.js b/src/utils.js index 7ed20a3..efdc641 100644 --- a/src/utils.js +++ b/src/utils.js @@ -119,7 +119,7 @@ const getMarkdownIdOrAnchorNameFragments = (content) => { } const anchorIdOrName = anchorMatch[1] - if (anchorIdOrName === undefined) { + if (anchorIdOrName.length <= 0) { continue } @@ -136,5 +136,5 @@ module.exports = { filterTokens, convertHeadingToHTMLFragment, getMarkdownHeadings, - getMarkdownAnchorHTMLFragments: getMarkdownIdOrAnchorNameFragments, + getMarkdownIdOrAnchorNameFragments, } diff --git a/test/utils.test.js b/test/utils.test.js index 7d35c4b..d98ce1c 100644 --- a/test/utils.test.js +++ b/test/utils.test.js @@ -4,7 +4,7 @@ const assert = require("node:assert/strict") const { convertHeadingToHTMLFragment, getMarkdownHeadings, - getMarkdownAnchorHTMLFragments, + getMarkdownIdOrAnchorNameFragments, } = require("../src/utils.js") test("utils", async (t) => { @@ -36,18 +36,22 @@ test("utils", async (t) => { ) }) - await t.test("getMarkdownAnchorHTMLFragments", async () => { + await t.test("getMarkdownIdOrAnchorNameFragments", async () => { assert.deepStrictEqual( - getMarkdownAnchorHTMLFragments( + getMarkdownIdOrAnchorNameFragments( 'Link', ), ["#anchorId"], ) assert.deepStrictEqual( - getMarkdownAnchorHTMLFragments('Link'), + getMarkdownIdOrAnchorNameFragments('Link'), ["#anchorName"], ) - assert.deepStrictEqual(getMarkdownAnchorHTMLFragments("Link"), []) - assert.deepStrictEqual(getMarkdownAnchorHTMLFragments(""), []) + assert.deepStrictEqual( + getMarkdownIdOrAnchorNameFragments("Link"), + [], + ) + assert.deepStrictEqual(getMarkdownIdOrAnchorNameFragments(""), []) + assert.deepStrictEqual(getMarkdownIdOrAnchorNameFragments(""), []) }) })