mirror of
				https://github.com/theoludwig/markdownlint-rule-relative-links.git
				synced 2025-11-01 00:49:07 +01:00 
			
		
		
		
	refactor: early conditions first
This commit is contained in:
		
							
								
								
									
										46
									
								
								src/index.js
									
									
									
									
									
								
							
							
						
						
									
										46
									
								
								src/index.js
									
									
									
									
									
								
							@@ -7,7 +7,7 @@ const {
 | 
				
			|||||||
  filterTokens,
 | 
					  filterTokens,
 | 
				
			||||||
  convertHeadingToHTMLFragment,
 | 
					  convertHeadingToHTMLFragment,
 | 
				
			||||||
  getMarkdownHeadings,
 | 
					  getMarkdownHeadings,
 | 
				
			||||||
  getMarkdownAnchorHTMLFragments,
 | 
					  getMarkdownIdOrAnchorNameFragments,
 | 
				
			||||||
} = require("./utils.js")
 | 
					} = require("./utils.js")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/** @typedef {import('markdownlint').Rule} MarkdownLintRule */
 | 
					/** @typedef {import('markdownlint').Rule} MarkdownLintRule */
 | 
				
			||||||
@@ -46,13 +46,20 @@ const customRule = {
 | 
				
			|||||||
          }
 | 
					          }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (hrefSrc != null) {
 | 
					        if (hrefSrc == null) {
 | 
				
			||||||
 | 
					          continue
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const url = new URL(hrefSrc, pathToFileURL(params.name))
 | 
					        const url = new URL(hrefSrc, pathToFileURL(params.name))
 | 
				
			||||||
        const isRelative =
 | 
					        const isRelative =
 | 
				
			||||||
          url.protocol === "file:" &&
 | 
					          url.protocol === "file:" &&
 | 
				
			||||||
          !hrefSrc.startsWith("/") &&
 | 
					          !hrefSrc.startsWith("/") &&
 | 
				
			||||||
          !hrefSrc.startsWith("#")
 | 
					          !hrefSrc.startsWith("#")
 | 
				
			||||||
          if (isRelative) {
 | 
					
 | 
				
			||||||
 | 
					        if (!isRelative) {
 | 
				
			||||||
 | 
					          continue
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const detail = `"${hrefSrc}"`
 | 
					        const detail = `"${hrefSrc}"`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (!fs.existsSync(url)) {
 | 
					        if (!fs.existsSync(url)) {
 | 
				
			||||||
@@ -63,29 +70,42 @@ const customRule = {
 | 
				
			|||||||
          continue
 | 
					          continue
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (url.hash.length <= 0) {
 | 
				
			||||||
 | 
					          if (hrefSrc.includes("#")) {
 | 
				
			||||||
            if (type !== "link_open") {
 | 
					            if (type !== "link_open") {
 | 
				
			||||||
 | 
					              onError({
 | 
				
			||||||
 | 
					                lineNumber,
 | 
				
			||||||
 | 
					                detail: `${detail} should not have a fragment identifier as it is an image`,
 | 
				
			||||||
 | 
					              })
 | 
				
			||||||
              continue
 | 
					              continue
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (url.hash.length <= 0) {
 | 
					 | 
				
			||||||
              if (hrefSrc.includes("#")) {
 | 
					 | 
				
			||||||
            onError({
 | 
					            onError({
 | 
				
			||||||
              lineNumber,
 | 
					              lineNumber,
 | 
				
			||||||
              detail: `${detail} should have a valid fragment identifier`,
 | 
					              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
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (url.hash.length > 0) {
 | 
					 | 
				
			||||||
        const fileContent = fs.readFileSync(url, { encoding: "utf8" })
 | 
					        const fileContent = fs.readFileSync(url, { encoding: "utf8" })
 | 
				
			||||||
        const headings = getMarkdownHeadings(fileContent)
 | 
					        const headings = getMarkdownHeadings(fileContent)
 | 
				
			||||||
              const anchorHTMLFragments =
 | 
					        const idOrAnchorNameHTMLFragments =
 | 
				
			||||||
                getMarkdownAnchorHTMLFragments(fileContent)
 | 
					          getMarkdownIdOrAnchorNameFragments(fileContent)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /** @type {Map<string, number>} */
 | 
					        /** @type {Map<string, number>} */
 | 
				
			||||||
        const fragments = new Map()
 | 
					        const fragments = new Map()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
              const headingsHTMLFragments = headings.map((heading) => {
 | 
					        const fragmentsHTML = headings.map((heading) => {
 | 
				
			||||||
          const fragment = convertHeadingToHTMLFragment(heading)
 | 
					          const fragment = convertHeadingToHTMLFragment(heading)
 | 
				
			||||||
          const count = fragments.get(fragment) ?? 0
 | 
					          const count = fragments.get(fragment) ?? 0
 | 
				
			||||||
          fragments.set(fragment, count + 1)
 | 
					          fragments.set(fragment, count + 1)
 | 
				
			||||||
@@ -95,16 +115,14 @@ const customRule = {
 | 
				
			|||||||
          return fragment
 | 
					          return fragment
 | 
				
			||||||
        })
 | 
					        })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
              headingsHTMLFragments.push(...anchorHTMLFragments)
 | 
					        fragmentsHTML.push(...idOrAnchorNameHTMLFragments)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
              if (!headingsHTMLFragments.includes(url.hash)) {
 | 
					        if (!fragmentsHTML.includes(url.hash)) {
 | 
				
			||||||
          onError({
 | 
					          onError({
 | 
				
			||||||
            lineNumber,
 | 
					            lineNumber,
 | 
				
			||||||
            detail: `${detail} should have a valid fragment identifier`,
 | 
					            detail: `${detail} should have a valid fragment identifier`,
 | 
				
			||||||
          })
 | 
					          })
 | 
				
			||||||
              }
 | 
					          continue
 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    })
 | 
					    })
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -119,7 +119,7 @@ const getMarkdownIdOrAnchorNameFragments = (content) => {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const anchorIdOrName = anchorMatch[1]
 | 
					    const anchorIdOrName = anchorMatch[1]
 | 
				
			||||||
    if (anchorIdOrName === undefined) {
 | 
					    if (anchorIdOrName.length <= 0) {
 | 
				
			||||||
      continue
 | 
					      continue
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -136,5 +136,5 @@ module.exports = {
 | 
				
			|||||||
  filterTokens,
 | 
					  filterTokens,
 | 
				
			||||||
  convertHeadingToHTMLFragment,
 | 
					  convertHeadingToHTMLFragment,
 | 
				
			||||||
  getMarkdownHeadings,
 | 
					  getMarkdownHeadings,
 | 
				
			||||||
  getMarkdownAnchorHTMLFragments: getMarkdownIdOrAnchorNameFragments,
 | 
					  getMarkdownIdOrAnchorNameFragments,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,7 +4,7 @@ const assert = require("node:assert/strict")
 | 
				
			|||||||
const {
 | 
					const {
 | 
				
			||||||
  convertHeadingToHTMLFragment,
 | 
					  convertHeadingToHTMLFragment,
 | 
				
			||||||
  getMarkdownHeadings,
 | 
					  getMarkdownHeadings,
 | 
				
			||||||
  getMarkdownAnchorHTMLFragments,
 | 
					  getMarkdownIdOrAnchorNameFragments,
 | 
				
			||||||
} = require("../src/utils.js")
 | 
					} = require("../src/utils.js")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
test("utils", async (t) => {
 | 
					test("utils", async (t) => {
 | 
				
			||||||
@@ -36,18 +36,22 @@ test("utils", async (t) => {
 | 
				
			|||||||
    )
 | 
					    )
 | 
				
			||||||
  })
 | 
					  })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  await t.test("getMarkdownAnchorHTMLFragments", async () => {
 | 
					  await t.test("getMarkdownIdOrAnchorNameFragments", async () => {
 | 
				
			||||||
    assert.deepStrictEqual(
 | 
					    assert.deepStrictEqual(
 | 
				
			||||||
      getMarkdownAnchorHTMLFragments(
 | 
					      getMarkdownIdOrAnchorNameFragments(
 | 
				
			||||||
        '<a name="anchorName" id="anchorId">Link</a>',
 | 
					        '<a name="anchorName" id="anchorId">Link</a>',
 | 
				
			||||||
      ),
 | 
					      ),
 | 
				
			||||||
      ["#anchorId"],
 | 
					      ["#anchorId"],
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
    assert.deepStrictEqual(
 | 
					    assert.deepStrictEqual(
 | 
				
			||||||
      getMarkdownAnchorHTMLFragments('<a name="anchorName">Link</a>'),
 | 
					      getMarkdownIdOrAnchorNameFragments('<a name="anchorName">Link</a>'),
 | 
				
			||||||
      ["#anchorName"],
 | 
					      ["#anchorName"],
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
    assert.deepStrictEqual(getMarkdownAnchorHTMLFragments("<a>Link</a>"), [])
 | 
					    assert.deepStrictEqual(
 | 
				
			||||||
    assert.deepStrictEqual(getMarkdownAnchorHTMLFragments("<a>"), [])
 | 
					      getMarkdownIdOrAnchorNameFragments("<a>Link</a>"),
 | 
				
			||||||
 | 
					      [],
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					    assert.deepStrictEqual(getMarkdownIdOrAnchorNameFragments("<a>"), [])
 | 
				
			||||||
 | 
					    assert.deepStrictEqual(getMarkdownIdOrAnchorNameFragments("<a id=>"), [])
 | 
				
			||||||
  })
 | 
					  })
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user