mirror of
https://github.com/DavidAnson/markdownlint.git
synced 2025-12-26 18:48:48 +01:00
Update MD051/link-fragments to handle links and images in headings (fixes #945).
This commit is contained in:
parent
6a2b86753b
commit
a736588958
5 changed files with 133 additions and 47 deletions
35
lib/md051.js
35
lib/md051.js
|
|
@ -3,13 +3,18 @@
|
|||
"use strict";
|
||||
|
||||
const { addError, addErrorDetailIf } = require("../helpers");
|
||||
const { filterByTypes, getHtmlTagInfo } = require("../helpers/micromark.cjs");
|
||||
const { filterByPredicate, filterByTypes, getHtmlTagInfo } =
|
||||
require("../helpers/micromark.cjs");
|
||||
|
||||
// Regular expression for identifying HTML anchor names
|
||||
const idRe = /\sid\s*=\s*['"]?([^'"\s>]+)/iu;
|
||||
const nameRe = /\sname\s*=\s*['"]?([^'"\s>]+)/iu;
|
||||
const anchorRe = /\{(#[a-z\d]+(?:[-_][a-z\d]+)*)\}/gu;
|
||||
|
||||
// Sets for filtering heading tokens during conversion
|
||||
const childrenExclude = new Set([ "image", "reference", "resource" ]);
|
||||
const tokensInclude = new Set([ "codeTextData", "data" ]);
|
||||
|
||||
/**
|
||||
* Converts a Markdown heading into an HTML fragment according to the rules
|
||||
* used by GitHub.
|
||||
|
|
@ -19,7 +24,11 @@ const anchorRe = /\{(#[a-z\d]+(?:[-_][a-z\d]+)*)\}/gu;
|
|||
*/
|
||||
function convertHeadingToHTMLFragment(headingText) {
|
||||
const inlineText =
|
||||
filterByTypes(headingText.children, [ "codeTextData", "data" ])
|
||||
filterByPredicate(
|
||||
headingText.children,
|
||||
(token) => tokensInclude.has(token.type),
|
||||
(token) => (childrenExclude.has(token.type) ? [] : token.children)
|
||||
)
|
||||
.map((token) => token.text)
|
||||
.join("");
|
||||
return "#" + encodeURIComponent(
|
||||
|
|
@ -52,16 +61,18 @@ module.exports = {
|
|||
);
|
||||
for (const headingText of headingTexts) {
|
||||
const fragment = convertHeadingToHTMLFragment(headingText);
|
||||
const count = fragments.get(fragment) || 0;
|
||||
if (count) {
|
||||
fragments.set(`${fragment}-${count}`, 0);
|
||||
}
|
||||
fragments.set(fragment, count + 1);
|
||||
let match = null;
|
||||
while ((match = anchorRe.exec(headingText.text)) !== null) {
|
||||
const [ , anchor ] = match;
|
||||
if (!fragments.has(anchor)) {
|
||||
fragments.set(anchor, 1);
|
||||
if (fragment !== "#") {
|
||||
const count = fragments.get(fragment) || 0;
|
||||
if (count) {
|
||||
fragments.set(`${fragment}-${count}`, 0);
|
||||
}
|
||||
fragments.set(fragment, count + 1);
|
||||
let match = null;
|
||||
while ((match = anchorRe.exec(headingText.text)) !== null) {
|
||||
const [ , anchor ] = match;
|
||||
if (!fragments.has(anchor)) {
|
||||
fragments.set(anchor, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue