mirror of
				https://github.com/theoludwig/markdownlint-rule-relative-links.git
				synced 2025-09-09 19:39:29 +02:00 
			
		
		
		
	refactor: early conditions first
This commit is contained in:
		
							
								
								
									
										122
									
								
								src/index.js
									
									
									
									
									
								
							
							
						
						
									
										122
									
								
								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<string, number>} */ | ||||
|               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<string, number>} */ | ||||
|         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 | ||||
|         } | ||||
|       } | ||||
|     }) | ||||
|   | ||||
| @@ -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, | ||||
| } | ||||
|   | ||||
| @@ -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( | ||||
|         '<a name="anchorName" id="anchorId">Link</a>', | ||||
|       ), | ||||
|       ["#anchorId"], | ||||
|     ) | ||||
|     assert.deepStrictEqual( | ||||
|       getMarkdownAnchorHTMLFragments('<a name="anchorName">Link</a>'), | ||||
|       getMarkdownIdOrAnchorNameFragments('<a name="anchorName">Link</a>'), | ||||
|       ["#anchorName"], | ||||
|     ) | ||||
|     assert.deepStrictEqual(getMarkdownAnchorHTMLFragments("<a>Link</a>"), []) | ||||
|     assert.deepStrictEqual(getMarkdownAnchorHTMLFragments("<a>"), []) | ||||
|     assert.deepStrictEqual( | ||||
|       getMarkdownIdOrAnchorNameFragments("<a>Link</a>"), | ||||
|       [], | ||||
|     ) | ||||
|     assert.deepStrictEqual(getMarkdownIdOrAnchorNameFragments("<a>"), []) | ||||
|     assert.deepStrictEqual(getMarkdownIdOrAnchorNameFragments("<a id=>"), []) | ||||
|   }) | ||||
| }) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user