2022-08-08 21:05:50 -07:00
/*! markdownlint 0.26.2 https://github.com/DavidAnson/markdownlint @license MIT */
Update dependencies: c8 to 7.7.2, eslint to 7.28.0, eslint-plugin-jsdoc to 35.1.3, eslint-plugin-unicorn to 33.0.1, globby to 11.0.3, js-yaml to 4.1.0, markdown-it-texmath to 0.9.0, markdownlint-rule-helpers to 0.14.0, ts-loader to 9.2.3, typescript to 4.3.2, webpack to 5.38.1, webpack-cli to 4.7.2.
2021-06-08 22:20:13 -07:00
var markdownlint ;
2021-01-05 20:55:09 -08:00
/******/ ( ( ) => { // webpackBootstrap
/******/ var _ _webpack _modules _ _ = ( {
2019-10-02 20:10:42 -07:00
2021-01-06 19:45:15 -08:00
/***/ "../lib sync recursive" :
/ * ! * * * * * * * * * * * * * * * * * * * * ! * \
! * * * . . / lib / sync * * * !
\ * * * * * * * * * * * * * * * * * * * * /
/***/ ( ( module ) => {
function webpackEmptyContext ( req ) {
var e = new Error ( "Cannot find module '" + req + "'" ) ;
e . code = 'MODULE_NOT_FOUND' ;
throw e ;
}
2021-02-06 19:23:55 -08:00
webpackEmptyContext . keys = ( ) => ( [ ] ) ;
2021-01-06 19:45:15 -08:00
webpackEmptyContext . resolve = webpackEmptyContext ;
webpackEmptyContext . id = "../lib sync recursive" ;
module . exports = webpackEmptyContext ;
/***/ } ) ,
/***/ "../helpers/helpers.js" :
/ * ! * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ! * \
! * * * . . / helpers / helpers . js * * * !
\ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
2022-05-04 22:09:11 -07:00
/***/ ( ( module , _ _unused _webpack _exports , _ _webpack _require _ _ ) => {
2019-10-02 20:10:42 -07:00
"use strict" ;
2021-01-05 20:55:09 -08:00
// @ts-check
2019-10-02 20:10:42 -07:00
// Regular expression for matching common newline characters
// See NEWLINES_RE in markdown-it/lib/rules_core/normalize.js
2022-06-02 21:42:48 -07:00
const newLineRe = /\r\n?|\n/g ;
2019-10-02 20:10:42 -07:00
module . exports . newLineRe = newLineRe ;
// Regular expression for matching common front matter (YAML and TOML)
module . exports . frontMatterRe =
// eslint-disable-next-line max-len
2020-11-24 16:37:11 -08:00
/((^---\s*$[^]*?^---\s*$)|(^\+\+\+\s*$[^]*?^(\+\+\+|\.\.\.)\s*$)|(^\{\s*$[^]*?^\}\s*$))(\r\n|\r|\n|$)/m ;
2022-02-12 17:46:46 -08:00
// Regular expression for matching the start of inline disable/enable comments
2022-06-02 21:42:48 -07:00
const inlineCommentStartRe =
2019-10-02 20:10:42 -07:00
// eslint-disable-next-line max-len
2022-05-15 15:59:11 -07:00
/(<!--\s*markdownlint-(disable|enable|capture|restore|disable-file|enable-file|disable-line|disable-next-line|configure-file))(?:\s|-->)/ig ;
2022-02-12 17:46:46 -08:00
module . exports . inlineCommentStartRe = inlineCommentStartRe ;
2022-04-10 05:37:57 +00:00
// Regular expression for matching HTML elements
2022-06-02 22:17:32 -07:00
const htmlElementRe = /<(([A-Za-z][A-Za-z0-9-]*)(?:\s[^`>]*)?)\/?>/g ;
2022-04-25 21:50:33 -07:00
module . exports . htmlElementRe = htmlElementRe ;
2019-10-02 20:10:42 -07:00
// Regular expressions for range matching
2020-06-23 20:14:58 -07:00
module . exports . bareUrlRe = /(?:http|ftp)s?:\/\/[^\s\]"']*(?:\/|[^\s\]"'\W])/ig ;
2019-12-14 13:50:48 -08:00
module . exports . listItemMarkerRe = /^([\s>]*)(?:[*+-]|\d+[.)])\s+/ ;
2019-10-02 20:10:42 -07:00
module . exports . orderedListItemMarkerRe = /^[\s>]*0*(\d+)[.)]/ ;
2020-05-14 21:49:05 -07:00
// Regular expression for all instances of emphasis markers
2022-06-02 21:42:48 -07:00
const emphasisMarkersRe = /[_*]/g ;
2022-08-01 18:48:01 -07:00
// Regular expression for blockquote prefixes
const blockquotePrefixRe = /^[>\s]*/ ;
module . exports . blockquotePrefixRe = blockquotePrefixRe ;
2022-07-30 16:12:27 -07:00
// Regular expression for reference links (full, collapsed, and shortcut)
2022-08-31 22:46:19 -07:00
const referenceLinkRe = /!?\\?\[((?:\[[^\]\0]*]|[^[\]\0])*)](?:(?:\[([^\]\0]*)\])|([^(])|$)/g ;
2022-06-01 20:23:08 -07:00
// Regular expression for link reference definitions
2022-06-02 21:42:48 -07:00
const linkReferenceDefinitionRe = /^ {0,3}\[([^\]]*[^\\])]:/ ;
2022-06-01 20:23:08 -07:00
module . exports . linkReferenceDefinitionRe = linkReferenceDefinitionRe ;
2019-10-02 20:10:42 -07:00
// All punctuation characters (normal and full-width)
2022-06-02 21:42:48 -07:00
const allPunctuation = ".,;:!?。,;:!?" ;
2020-11-24 16:37:11 -08:00
module . exports . allPunctuation = allPunctuation ;
// All punctuation characters without question mark (normal and full-width)
module . exports . allPunctuationNoQuestion = allPunctuation . replace ( /[?? ]/gu , "" ) ;
2019-10-02 20:10:42 -07:00
// Returns true iff the input is a number
module . exports . isNumber = function isNumber ( obj ) {
return typeof obj === "number" ;
} ;
// Returns true iff the input is a string
module . exports . isString = function isString ( obj ) {
return typeof obj === "string" ;
} ;
// Returns true iff the input string is empty
module . exports . isEmptyString = function isEmptyString ( str ) {
return str . length === 0 ;
} ;
// Returns true iff the input is an object
module . exports . isObject = function isObject ( obj ) {
return ( obj !== null ) && ( typeof obj === "object" ) && ! Array . isArray ( obj ) ;
} ;
2022-02-11 21:54:43 -08:00
/ * *
* Returns true iff the input line is blank ( contains nothing , whitespace , or
* comments ( unclosed start / end comments allowed ) ) .
*
* @ param { string } line Input line .
* @ returns { boolean } True iff line is blank .
* /
function isBlankLine ( line ) {
2022-06-02 21:42:48 -07:00
const startComment = "<!--" ;
const endComment = "-->" ;
const removeComments = ( s ) => {
2022-02-11 21:54:43 -08:00
// eslint-disable-next-line no-constant-condition
while ( true ) {
2022-06-02 21:42:48 -07:00
const start = s . indexOf ( startComment ) ;
const end = s . indexOf ( endComment ) ;
2022-02-11 21:54:43 -08:00
if ( ( end !== - 1 ) && ( ( start === - 1 ) || ( end < start ) ) ) {
// Unmatched end comment is first
s = s . slice ( end + endComment . length ) ;
}
else if ( ( start !== - 1 ) && ( end !== - 1 ) ) {
// Start comment is before end comment
s = s . slice ( 0 , start ) + s . slice ( end + endComment . length ) ;
}
else if ( ( start !== - 1 ) && ( end === - 1 ) ) {
// Unmatched start comment is last
s = s . slice ( 0 , start ) ;
}
else {
// No more comments to remove
return s ;
}
}
} ;
2021-12-20 04:18:45 +00:00
return ( ! line ||
! line . trim ( ) ||
2022-02-11 21:54:43 -08:00
! removeComments ( line ) . replace ( />/g , "" ) . trim ( ) ) ;
}
module . exports . isBlankLine = isBlankLine ;
2020-01-27 19:19:34 -08:00
/ * *
* Compare function for Array . prototype . sort for ascending order of numbers .
*
* @ param { number } a First number .
* @ param { number } b Second number .
* @ returns { number } Positive value if a > b , negative value if b < a , 0 otherwise .
* /
module . exports . numericSortAscending = function numericSortAscending ( a , b ) {
return a - b ;
} ;
2019-10-02 20:10:42 -07:00
// Returns true iff the sorted array contains the specified element
module . exports . includesSorted = function includesSorted ( array , element ) {
2022-06-02 21:42:48 -07:00
let left = 0 ;
let right = array . length - 1 ;
2019-10-02 20:10:42 -07:00
while ( left <= right ) {
2020-09-13 21:15:11 -07:00
// eslint-disable-next-line no-bitwise
2022-06-02 21:42:48 -07:00
const mid = ( left + right ) >> 1 ;
2019-10-02 20:10:42 -07:00
if ( array [ mid ] < element ) {
left = mid + 1 ;
}
else if ( array [ mid ] > element ) {
right = mid - 1 ;
}
else {
return true ;
}
}
return false ;
} ;
2021-01-30 14:36:11 -08:00
// Replaces the content of properly-formatted CommonMark comments with "."
2019-10-02 20:10:42 -07:00
// This preserves the line/column information for the rest of the document
2021-01-30 13:08:57 -08:00
// https://spec.commonmark.org/0.29/#html-blocks
// https://spec.commonmark.org/0.29/#html-comment
2022-06-02 21:42:48 -07:00
const htmlCommentBegin = "<!--" ;
const htmlCommentEnd = "-->" ;
2022-10-14 20:59:42 -07:00
const safeCommentCharacter = "." ;
const startsWithPipeRe = /^ *\|/ ;
const notCrLfRe = /[^\r\n]/g ;
const notSpaceCrLfRe = /[^ \r\n]/g ;
const trailingSpaceRe = / +[\r\n]/g ;
const replaceTrailingSpace = ( s ) => s . replace ( notCrLfRe , safeCommentCharacter ) ;
2019-10-02 20:10:42 -07:00
module . exports . clearHtmlCommentText = function clearHtmlCommentText ( text ) {
2022-06-02 21:42:48 -07:00
let i = 0 ;
2019-10-02 20:10:42 -07:00
while ( ( i = text . indexOf ( htmlCommentBegin , i ) ) !== - 1 ) {
2022-06-02 21:42:48 -07:00
const j = text . indexOf ( htmlCommentEnd , i + 2 ) ;
2019-10-02 20:10:42 -07:00
if ( j === - 1 ) {
2020-04-11 13:54:46 -07:00
// Un-terminated comments are treated as text
break ;
2019-10-02 20:10:42 -07:00
}
2021-01-30 13:08:57 -08:00
// If the comment has content...
if ( j > i + htmlCommentBegin . length ) {
2022-10-14 20:59:42 -07:00
const content = text . slice ( i + htmlCommentBegin . length , j ) ;
const lastLf = text . lastIndexOf ( "\n" , i ) + 1 ;
const preText = text . slice ( lastLf , i ) ;
const isBlock = preText . trim ( ) . length === 0 ;
const couldBeTable = startsWithPipeRe . test ( preText ) ;
const spansTableCells = couldBeTable && content . includes ( "\n" ) ;
const isValid = isBlock ||
! ( spansTableCells ||
content . startsWith ( ">" ) ||
content . startsWith ( "->" ) ||
content . endsWith ( "-" ) ||
content . includes ( "--" ) ) ;
// If a valid block/inline comment...
if ( isValid ) {
const clearedContent = content
. replace ( notSpaceCrLfRe , safeCommentCharacter )
. replace ( trailingSpaceRe , replaceTrailingSpace ) ;
text =
text . slice ( 0 , i + htmlCommentBegin . length ) +
clearedContent +
text . slice ( j ) ;
2021-01-30 13:08:57 -08:00
}
2019-10-02 20:10:42 -07:00
}
i = j + htmlCommentEnd . length ;
}
return text ;
} ;
// Escapes a string for use in a RegExp
module . exports . escapeForRegExp = function escapeForRegExp ( str ) {
return str . replace ( /[-/\\^$*+?.()|[\]{}]/g , "\\$&" ) ;
} ;
// Un-escapes Markdown content (simple algorithm; not a parser)
2022-06-02 21:42:48 -07:00
const escapedMarkdownRe = /\\./g ;
2019-10-02 20:10:42 -07:00
module . exports . unescapeMarkdown =
function unescapeMarkdown ( markdown , replacement ) {
2022-06-02 21:42:48 -07:00
return markdown . replace ( escapedMarkdownRe , ( match ) => {
const char = match [ 1 ] ;
2019-10-02 20:10:42 -07:00
if ( "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~" . includes ( char ) ) {
return replacement || char ;
}
return match ;
} ) ;
} ;
2020-01-27 19:19:34 -08:00
/ * *
* Return the string representation of a fence markup character .
*
* @ param { string } markup Fence string .
* @ returns { string } String representation .
* /
module . exports . fencedCodeBlockStyleFor =
function fencedCodeBlockStyleFor ( markup ) {
switch ( markup [ 0 ] ) {
case "~" :
return "tilde" ;
default :
return "backtick" ;
}
} ;
2021-10-21 06:42:48 +02:00
/ * *
* Return the string representation of a emphasis or strong markup character .
*
* @ param { string } markup Emphasis or strong string .
* @ returns { string } String representation .
* /
module . exports . emphasisOrStrongStyleFor =
function emphasisOrStrongStyleFor ( markup ) {
switch ( markup [ 0 ] ) {
case "*" :
return "asterisk" ;
default :
return "underscore" ;
}
} ;
2020-01-27 19:19:34 -08:00
/ * *
* Return the number of characters of indent for a token .
*
* @ param { Object } token MarkdownItToken instance .
* @ returns { number } Characters of indent .
* /
2019-10-02 20:10:42 -07:00
function indentFor ( token ) {
2022-06-02 21:42:48 -07:00
const line = token . line . replace ( /^[\s>]*(> |>)/ , "" ) ;
2021-02-06 19:55:22 -08:00
return line . length - line . trimStart ( ) . length ;
2019-10-02 20:10:42 -07:00
}
module . exports . indentFor = indentFor ;
// Returns the heading style for a heading token
module . exports . headingStyleFor = function headingStyleFor ( token ) {
if ( ( token . map [ 1 ] - token . map [ 0 ] ) === 1 ) {
if ( /[^\\]#\s*$/ . test ( token . line ) ) {
return "atx_closed" ;
}
return "atx" ;
}
return "setext" ;
} ;
2020-01-27 19:19:34 -08:00
/ * *
* Return the string representation of an unordered list marker .
*
* @ param { Object } token MarkdownItToken instance .
* @ returns { string } String representation .
* /
module . exports . unorderedListStyleFor = function unorderedListStyleFor ( token ) {
switch ( token . markup ) {
case "-" :
return "dash" ;
case "+" :
return "plus" ;
// case "*":
default :
return "asterisk" ;
}
} ;
/ * *
* Calls the provided function for each matching token .
*
* @ param { Object } params RuleParams instance .
* @ param { string } type Token type identifier .
* @ param { Function } handler Callback function .
* @ returns { void }
* /
2019-10-02 20:10:42 -07:00
function filterTokens ( params , type , handler ) {
2022-06-07 22:59:48 -07:00
for ( const token of params . tokens ) {
2019-10-02 20:10:42 -07:00
if ( token . type === type ) {
handler ( token ) ;
}
2022-06-07 22:59:48 -07:00
}
2019-10-02 20:10:42 -07:00
}
module . exports . filterTokens = filterTokens ;
2021-01-24 17:50:39 -08:00
/ * *
* Returns whether a token is a math block ( created by markdown - it - texmath ) .
*
* @ param { Object } token MarkdownItToken instance .
* @ returns { boolean } True iff token is a math block .
* /
function isMathBlock ( token ) {
2021-12-17 01:56:42 +00:00
return ( ( ( token . tag === "$$" ) || ( token . tag === "math" ) ) &&
2021-01-24 17:50:39 -08:00
token . type . startsWith ( "math_block" ) &&
! token . type . endsWith ( "_end" ) ) ;
}
2021-12-23 04:34:25 +00:00
module . exports . isMathBlock = isMathBlock ;
2019-10-02 20:10:42 -07:00
// Get line metadata array
module . exports . getLineMetadata = function getLineMetadata ( params ) {
2022-06-02 21:42:48 -07:00
const lineMetadata = params . lines . map ( ( line , index ) => [ line , index , false , 0 , false , false , false , false ] ) ;
filterTokens ( params , "fence" , ( token ) => {
2019-10-02 20:10:42 -07:00
lineMetadata [ token . map [ 0 ] ] [ 3 ] = 1 ;
lineMetadata [ token . map [ 1 ] - 1 ] [ 3 ] = - 1 ;
2022-06-02 21:42:48 -07:00
for ( let i = token . map [ 0 ] + 1 ; i < token . map [ 1 ] - 1 ; i ++ ) {
2019-10-02 20:10:42 -07:00
lineMetadata [ i ] [ 2 ] = true ;
}
} ) ;
2022-06-02 21:42:48 -07:00
filterTokens ( params , "code_block" , ( token ) => {
for ( let i = token . map [ 0 ] ; i < token . map [ 1 ] ; i ++ ) {
2019-10-02 20:10:42 -07:00
lineMetadata [ i ] [ 2 ] = true ;
}
} ) ;
2022-06-02 21:42:48 -07:00
filterTokens ( params , "table_open" , ( token ) => {
for ( let i = token . map [ 0 ] ; i < token . map [ 1 ] ; i ++ ) {
2019-10-02 20:10:42 -07:00
lineMetadata [ i ] [ 4 ] = true ;
}
} ) ;
2022-06-02 21:42:48 -07:00
filterTokens ( params , "list_item_open" , ( token ) => {
let count = 1 ;
for ( let i = token . map [ 0 ] ; i < token . map [ 1 ] ; i ++ ) {
2020-04-11 13:54:46 -07:00
lineMetadata [ i ] [ 5 ] = count ;
count ++ ;
2019-10-02 20:10:42 -07:00
}
} ) ;
2022-06-02 21:42:48 -07:00
filterTokens ( params , "hr" , ( token ) => {
2020-04-11 13:54:46 -07:00
lineMetadata [ token . map [ 0 ] ] [ 6 ] = true ;
} ) ;
2022-06-08 22:10:27 -07:00
for ( const token of params . tokens . filter ( isMathBlock ) ) {
2022-06-02 21:42:48 -07:00
for ( let i = token . map [ 0 ] ; i < token . map [ 1 ] ; i ++ ) {
2021-01-24 17:50:39 -08:00
lineMetadata [ i ] [ 7 ] = true ;
}
2022-06-08 22:10:27 -07:00
}
2019-10-02 20:10:42 -07:00
return lineMetadata ;
} ;
2021-11-23 04:40:05 +00:00
/ * *
* Calls the provided function for each line .
*
* @ param { Object } lineMetadata Line metadata object .
* @ param { Function } handler Function taking ( line , lineIndex , inCode , onFence ,
* inTable , inItem , inBreak , inMath ) .
* @ returns { void }
* /
function forEachLine ( lineMetadata , handler ) {
2022-06-08 22:10:27 -07:00
for ( const metadata of lineMetadata ) {
2022-06-02 21:42:48 -07:00
handler ( ... metadata ) ;
2022-06-08 22:10:27 -07:00
}
2021-11-23 04:40:05 +00:00
}
module . exports . forEachLine = forEachLine ;
2019-10-02 20:10:42 -07:00
// Returns (nested) lists as a flat array (in order)
2021-06-17 22:01:27 -07:00
module . exports . flattenLists = function flattenLists ( tokens ) {
2022-06-02 21:42:48 -07:00
const flattenedLists = [ ] ;
const stack = [ ] ;
let current = null ;
let nesting = 0 ;
const nestingStack = [ ] ;
let lastWithMap = { "map" : [ 0 , 1 ] } ;
2022-06-08 22:10:27 -07:00
for ( const token of tokens ) {
2019-10-02 20:10:42 -07:00
if ( ( token . type === "bullet_list_open" ) ||
( token . type === "ordered_list_open" ) ) {
// Save current context and start a new one
stack . push ( current ) ;
current = {
"unordered" : ( token . type === "bullet_list_open" ) ,
"parentsUnordered" : ! current ||
( current . unordered && current . parentsUnordered ) ,
"open" : token ,
"indent" : indentFor ( token ) ,
"parentIndent" : ( current && current . indent ) || 0 ,
"items" : [ ] ,
2020-04-11 13:54:46 -07:00
"nesting" : nesting ,
2019-10-02 20:10:42 -07:00
"lastLineIndex" : - 1 ,
"insert" : flattenedLists . length
} ;
2020-04-11 13:54:46 -07:00
nesting ++ ;
2019-10-02 20:10:42 -07:00
}
else if ( ( token . type === "bullet_list_close" ) ||
( token . type === "ordered_list_close" ) ) {
// Finalize current context and restore previous
current . lastLineIndex = lastWithMap . map [ 1 ] ;
flattenedLists . splice ( current . insert , 0 , current ) ;
delete current . insert ;
current = stack . pop ( ) ;
2020-04-11 13:54:46 -07:00
nesting -- ;
2019-10-02 20:10:42 -07:00
}
else if ( token . type === "list_item_open" ) {
// Add list item
current . items . push ( token ) ;
}
2020-04-11 13:54:46 -07:00
else if ( token . type === "blockquote_open" ) {
nestingStack . push ( nesting ) ;
nesting = 0 ;
}
else if ( token . type === "blockquote_close" ) {
2022-06-12 17:51:47 -07:00
nesting = nestingStack . pop ( ) || 0 ;
2020-04-11 13:54:46 -07:00
}
2022-06-07 22:16:34 -07:00
if ( token . map ) {
2019-10-02 20:10:42 -07:00
// Track last token with map
lastWithMap = token ;
}
2022-06-08 22:10:27 -07:00
}
2019-10-02 20:10:42 -07:00
return flattenedLists ;
} ;
// Calls the provided function for each specified inline child token
module . exports . forEachInlineChild =
function forEachInlineChild ( params , type , handler ) {
filterTokens ( params , "inline" , function forToken ( token ) {
2022-06-08 22:10:27 -07:00
for ( const child of token . children ) {
2019-10-02 20:10:42 -07:00
if ( child . type === type ) {
handler ( child , token ) ;
}
2022-06-08 22:10:27 -07:00
}
2019-10-02 20:10:42 -07:00
} ) ;
} ;
// Calls the provided function for each heading's content
module . exports . forEachHeading = function forEachHeading ( params , handler ) {
2022-06-02 21:42:48 -07:00
let heading = null ;
2022-06-08 22:10:27 -07:00
for ( const token of params . tokens ) {
2019-10-02 20:10:42 -07:00
if ( token . type === "heading_open" ) {
heading = token ;
}
else if ( token . type === "heading_close" ) {
heading = null ;
}
else if ( ( token . type === "inline" ) && heading ) {
2022-04-10 05:37:57 +00:00
handler ( heading , token . content , token ) ;
2019-10-02 20:10:42 -07:00
}
2022-06-08 22:10:27 -07:00
}
2019-10-02 20:10:42 -07:00
} ;
2020-04-25 21:15:13 -07:00
/ * *
* Calls the provided function for each inline code span ' s content .
*
* @ param { string } input Markdown content .
2021-11-23 04:40:05 +00:00
* @ param { Function } handler Callback function taking ( code , lineIndex ,
* columnIndex , ticks ) .
2020-04-25 21:15:13 -07:00
* @ returns { void }
* /
function forEachInlineCodeSpan ( input , handler ) {
2022-06-19 02:14:03 +00:00
const backtickRe = /`+/g ;
let match = null ;
const backticksLengthAndIndex = [ ] ;
while ( ( match = backtickRe . exec ( input ) ) !== null ) {
backticksLengthAndIndex . push ( [ match [ 0 ] . length , match . index ] ) ;
}
const newLinesIndex = [ ] ;
while ( ( match = newLineRe . exec ( input ) ) !== null ) {
newLinesIndex . push ( match . index ) ;
}
let lineIndex = 0 ;
let lineStartIndex = 0 ;
let k = 0 ;
for ( let i = 0 ; i < backticksLengthAndIndex . length - 1 ; i ++ ) {
const [ startLength , startIndex ] = backticksLengthAndIndex [ i ] ;
if ( ( startIndex === 0 ) || ( input [ startIndex - 1 ] !== "\\" ) ) {
for ( let j = i + 1 ; j < backticksLengthAndIndex . length ; j ++ ) {
const [ endLength , endIndex ] = backticksLengthAndIndex [ j ] ;
if ( startLength === endLength ) {
for ( ; k < newLinesIndex . length ; k ++ ) {
const newLineIndex = newLinesIndex [ k ] ;
if ( startIndex < newLineIndex ) {
break ;
}
lineIndex ++ ;
lineStartIndex = newLineIndex + 1 ;
}
const columnIndex = startIndex - lineStartIndex + startLength ;
handler ( input . slice ( startIndex + startLength , endIndex ) , lineIndex , columnIndex , startLength ) ;
i = j ;
break ;
2020-04-25 21:15:13 -07:00
}
}
}
}
}
module . exports . forEachInlineCodeSpan = forEachInlineCodeSpan ;
2022-06-01 20:23:08 -07:00
/ * *
* Adds ellipsis to the left / right / middle of the specified text .
*
* @ param { string } text Text to ellipsify .
* @ param { boolean } [ start ] True iff the start of the text is important .
* @ param { boolean } [ end ] True iff the end of the text is important .
* @ returns { string } Ellipsified text .
* /
function ellipsify ( text , start , end ) {
if ( text . length <= 30 ) {
// Nothing to do
}
else if ( start && end ) {
text = text . slice ( 0 , 15 ) + "..." + text . slice ( - 15 ) ;
}
else if ( end ) {
text = "..." + text . slice ( - 30 ) ;
}
else {
text = text . slice ( 0 , 30 ) + "..." ;
}
return text ;
}
module . exports . ellipsify = ellipsify ;
2020-01-27 19:19:34 -08:00
/ * *
* Adds a generic error object via the onError callback .
*
* @ param { Object } onError RuleOnError instance .
* @ param { number } lineNumber Line number .
* @ param { string } [ detail ] Error details .
* @ param { string } [ context ] Error context .
* @ param { number [ ] } [ range ] Column and length of error .
* @ param { Object } [ fixInfo ] RuleOnErrorFixInfo instance .
* @ returns { void }
* /
2019-10-02 20:10:42 -07:00
function addError ( onError , lineNumber , detail , context , range , fixInfo ) {
onError ( {
2022-06-02 21:42:48 -07:00
lineNumber ,
detail ,
context ,
range ,
fixInfo
2019-10-02 20:10:42 -07:00
} ) ;
}
module . exports . addError = addError ;
// Adds an error object with details conditionally via the onError callback
module . exports . addErrorDetailIf = function addErrorDetailIf ( onError , lineNumber , expected , actual , detail , context , range , fixInfo ) {
if ( expected !== actual ) {
addError ( onError , lineNumber , "Expected: " + expected + "; Actual: " + actual +
( detail ? "; " + detail : "" ) , context , range , fixInfo ) ;
}
} ;
// Adds an error object with context via the onError callback
module . exports . addErrorContext = function addErrorContext ( onError , lineNumber , context , left , right , range , fixInfo ) {
2022-06-01 20:23:08 -07:00
context = ellipsify ( context , left , right ) ;
2022-06-12 17:51:47 -07:00
addError ( onError , lineNumber , undefined , context , range , fixInfo ) ;
2019-10-02 20:10:42 -07:00
} ;
2021-06-17 21:50:03 -07:00
/ * *
2021-11-23 04:40:05 +00:00
* Returns an array of code block and span content ranges .
2021-06-17 21:50:03 -07:00
*
2021-11-23 04:40:05 +00:00
* @ param { Object } params RuleParams instance .
* @ param { Object } lineMetadata Line metadata object .
* @ returns { number [ ] [ ] } Array of ranges ( lineIndex , columnIndex , length ) .
2021-06-17 21:50:03 -07:00
* /
2022-06-02 21:42:48 -07:00
module . exports . codeBlockAndSpanRanges = ( params , lineMetadata ) => {
const exclusions = [ ] ;
2021-11-23 04:40:05 +00:00
// Add code block ranges (excludes fences)
2022-06-02 21:42:48 -07:00
forEachLine ( lineMetadata , ( line , lineIndex , inCode , onFence ) => {
2021-11-23 04:40:05 +00:00
if ( inCode && ! onFence ) {
2021-12-17 17:24:00 -08:00
exclusions . push ( [ lineIndex , 0 , line . length ] ) ;
2021-11-23 04:40:05 +00:00
}
} ) ;
// Add code span ranges (excludes ticks)
2022-06-02 21:42:48 -07:00
filterTokens ( params , "inline" , ( token ) => {
if ( token . children . some ( ( child ) => child . type === "code_inline" ) ) {
const tokenLines = params . lines . slice ( token . map [ 0 ] , token . map [ 1 ] ) ;
forEachInlineCodeSpan ( tokenLines . join ( "\n" ) , ( code , lineIndex , columnIndex ) => {
const codeLines = code . split ( newLineRe ) ;
for ( const [ i , line ] of codeLines . entries ( ) ) {
2021-11-23 04:40:05 +00:00
exclusions . push ( [
token . lineNumber - 1 + lineIndex + i ,
i ? 0 : columnIndex ,
line . length
] ) ;
2022-06-02 21:42:48 -07:00
}
2021-11-23 04:40:05 +00:00
} ) ;
2021-06-17 21:50:03 -07:00
}
} ) ;
return exclusions ;
} ;
2022-04-25 21:50:33 -07:00
/ * *
* Returns an array of HTML element ranges .
*
* @ param { Object } params RuleParams instance .
* @ param { Object } lineMetadata Line metadata object .
* @ returns { number [ ] [ ] } Array of ranges ( lineIndex , columnIndex , length ) .
* /
2022-06-02 21:42:48 -07:00
module . exports . htmlElementRanges = ( params , lineMetadata ) => {
const exclusions = [ ] ;
forEachLine ( lineMetadata , ( line , lineIndex , inCode ) => {
let match = null ;
2022-04-25 21:50:33 -07:00
// eslint-disable-next-line no-unmodified-loop-condition
while ( ! inCode && ( ( match = htmlElementRe . exec ( line ) ) !== null ) ) {
exclusions . push ( [ lineIndex , match . index , match [ 0 ] . length ] ) ;
}
} ) ;
return exclusions ;
} ;
2022-06-01 20:23:08 -07:00
/ * *
* Determines whether the specified range is within another range .
*
* @ param { number [ ] [ ] } ranges Array of ranges ( line , index , length ) .
* @ param { number } lineIndex Line index to check .
* @ param { number } index Index to check .
* @ param { number } length Length to check .
* @ returns { boolean } True iff the specified range is within .
* /
2022-06-02 21:42:48 -07:00
const withinAnyRange = ( ranges , lineIndex , index , length ) => ( ! ranges . every ( ( span ) => ( ( lineIndex !== span [ 0 ] ) ||
2022-06-01 20:23:08 -07:00
( index < span [ 1 ] ) ||
2022-06-02 21:42:48 -07:00
( index + length > span [ 1 ] + span [ 2 ] ) ) ) ) ;
2022-06-02 22:17:32 -07:00
module . exports . withinAnyRange = withinAnyRange ;
2019-10-02 20:10:42 -07:00
// Returns a range object for a line by applying a RegExp
module . exports . rangeFromRegExp = function rangeFromRegExp ( line , regexp ) {
2022-06-02 21:42:48 -07:00
let range = null ;
const match = line . match ( regexp ) ;
2019-10-02 20:10:42 -07:00
if ( match ) {
2022-06-02 21:42:48 -07:00
const column = match . index + 1 ;
const length = match [ 0 ] . length ;
2021-11-13 12:40:51 -08:00
range = [ column , length ] ;
2019-10-02 20:10:42 -07:00
}
return range ;
} ;
// Determines if the front matter includes a title
module . exports . frontMatterHasTitle =
function frontMatterHasTitle ( frontMatterLines , frontMatterTitlePattern ) {
2022-06-02 21:42:48 -07:00
const ignoreFrontMatter = ( frontMatterTitlePattern !== undefined ) && ! frontMatterTitlePattern ;
const frontMatterTitleRe = new RegExp ( String ( frontMatterTitlePattern || "^\\s*\"?title\"?\\s*[:=]" ) , "i" ) ;
2019-10-02 20:10:42 -07:00
return ! ignoreFrontMatter &&
2022-06-02 21:42:48 -07:00
frontMatterLines . some ( ( line ) => frontMatterTitleRe . test ( line ) ) ;
2019-10-02 20:10:42 -07:00
} ;
2022-02-18 21:14:14 -08:00
/ * *
* Calls the provided function for each link .
*
* @ param { string } line Line of Markdown input .
* @ param { Function } handler Function taking ( index , link , text , destination ) .
* @ returns { void }
* /
function forEachLink ( line , handler ) {
// Helper to find matching close symbol for link text/destination
2022-06-02 21:42:48 -07:00
const findClosingSymbol = ( index ) => {
const begin = line [ index ] ;
const end = ( begin === "[" ) ? "]" : ")" ;
let nesting = 0 ;
let escaping = false ;
let pointy = false ;
for ( let i = index + 1 ; i < line . length ; i ++ ) {
const current = line [ i ] ;
2022-02-18 21:14:14 -08:00
if ( current === "\\" ) {
escaping = ! escaping ;
}
else if ( ! escaping && ( current === begin ) ) {
nesting ++ ;
}
else if ( ! escaping && ( current === end ) ) {
if ( nesting > 0 ) {
nesting -- ;
}
else if ( ! pointy ) {
// Return index after matching close symbol
return i + 1 ;
}
}
else if ( ( i === index + 1 ) && ( begin === "(" ) && ( current === "<" ) ) {
pointy = true ;
}
else if ( ! escaping && pointy && current === ">" ) {
pointy = false ;
nesting = 0 ;
}
else {
escaping = false ;
}
}
// No match found
return - 1 ;
} ;
// Scan line for unescaped "[" character
2022-06-02 21:42:48 -07:00
let escaping = false ;
for ( let i = 0 ; i < line . length ; i ++ ) {
const current = line [ i ] ;
2022-02-18 21:14:14 -08:00
if ( current === "\\" ) {
escaping = ! escaping ;
}
else if ( ! escaping && ( current === "[" ) ) {
// Scan for matching close "]" of link text
2022-06-02 21:42:48 -07:00
const textEnd = findClosingSymbol ( i ) ;
2022-02-18 21:14:14 -08:00
if ( textEnd !== - 1 ) {
if ( ( line [ textEnd ] === "(" ) || ( line [ textEnd ] === "[" ) ) {
// Scan for matching close ")" or "]" of link destination
2022-06-02 21:42:48 -07:00
const destEnd = findClosingSymbol ( textEnd ) ;
2022-02-18 21:14:14 -08:00
if ( destEnd !== - 1 ) {
// Call handler with link text and destination
2022-06-02 21:42:48 -07:00
const link = line . slice ( i , destEnd ) ;
const text = line . slice ( i , textEnd ) ;
const dest = line . slice ( textEnd , destEnd ) ;
2022-02-18 21:14:14 -08:00
handler ( i , link , text , dest ) ;
i = destEnd ;
}
}
if ( i < textEnd ) {
// Call handler with link text only
2022-06-02 21:42:48 -07:00
const text = line . slice ( i , textEnd ) ;
2022-02-18 21:14:14 -08:00
handler ( i , text , text ) ;
i = textEnd ;
}
}
}
else {
escaping = false ;
}
}
}
module . exports . forEachLink = forEachLink ;
2020-04-25 21:15:13 -07:00
/ * *
2020-05-14 21:49:05 -07:00
* Returns a list of emphasis markers in code spans and links .
2020-04-25 21:15:13 -07:00
*
* @ param { Object } params RuleParams instance .
* @ returns { number [ ] [ ] } List of markers .
* /
2020-05-14 21:49:05 -07:00
function emphasisMarkersInContent ( params ) {
2022-06-02 21:42:48 -07:00
const { lines } = params ;
const byLine = new Array ( lines . length ) ;
2021-11-26 05:37:04 +00:00
// Search links
2022-06-08 22:10:27 -07:00
for ( const [ tokenLineIndex , tokenLine ] of lines . entries ( ) ) {
2022-06-02 21:42:48 -07:00
const inLine = [ ] ;
forEachLink ( tokenLine , ( index , match ) => {
let markerMatch = null ;
2022-02-18 21:14:14 -08:00
while ( ( markerMatch = emphasisMarkersRe . exec ( match ) ) ) {
inLine . push ( index + markerMatch . index ) ;
2021-11-26 05:37:04 +00:00
}
2022-02-18 21:14:14 -08:00
} ) ;
2021-11-26 05:37:04 +00:00
byLine [ tokenLineIndex ] = inLine ;
2022-06-08 22:10:27 -07:00
}
2020-05-14 21:49:05 -07:00
// Search code spans
2022-06-02 21:42:48 -07:00
filterTokens ( params , "inline" , ( token ) => {
const { children , lineNumber , map } = token ;
if ( children . some ( ( child ) => child . type === "code_inline" ) ) {
const tokenLines = lines . slice ( map [ 0 ] , map [ 1 ] ) ;
forEachInlineCodeSpan ( tokenLines . join ( "\n" ) , ( code , lineIndex , column , tickCount ) => {
const codeLines = code . split ( newLineRe ) ;
2022-06-08 22:10:27 -07:00
for ( const [ codeLineIndex , codeLine ] of codeLines . entries ( ) ) {
2022-06-02 21:42:48 -07:00
const byLineIndex = lineNumber - 1 + lineIndex + codeLineIndex ;
const inLine = byLine [ byLineIndex ] ;
const codeLineOffset = codeLineIndex ? 0 : column - 1 + tickCount ;
let match = null ;
2020-04-25 21:15:13 -07:00
while ( ( match = emphasisMarkersRe . exec ( codeLine ) ) ) {
inLine . push ( codeLineOffset + match . index ) ;
}
2021-11-26 05:37:04 +00:00
byLine [ byLineIndex ] = inLine ;
2022-06-08 22:10:27 -07:00
}
2020-04-25 21:15:13 -07:00
} ) ;
}
} ) ;
return byLine ;
}
2020-05-14 21:49:05 -07:00
module . exports . emphasisMarkersInContent = emphasisMarkersInContent ;
2022-06-01 20:23:08 -07:00
/ * *
* Returns an object with information about reference links and images .
*
* @ param { Object } lineMetadata Line metadata object .
* @ returns { Object } Reference link / image data .
* /
2022-06-12 18:39:28 -07:00
function getReferenceLinkImageData ( lineMetadata ) {
2022-06-01 20:23:08 -07:00
// Initialize return values
2022-06-02 21:42:48 -07:00
const references = new Map ( ) ;
const shortcuts = new Set ( ) ;
const definitions = new Map ( ) ;
const duplicateDefinitions = [ ] ;
2022-06-01 20:23:08 -07:00
// Define helper functions
2022-06-02 21:42:48 -07:00
const normalizeLabel = ( s ) => s . toLowerCase ( ) . trim ( ) . replace ( /\s+/g , " " ) ;
const exclusions = [ ] ;
2022-07-30 16:12:27 -07:00
const excluded = ( match ) => withinAnyRange ( exclusions , 0 , match . index , match [ 0 ] . length - ( match [ 3 ] || "" ) . length ) ;
2022-06-01 20:23:08 -07:00
// Convert input to single-line so multi-line links/images are easier
2022-06-02 21:42:48 -07:00
const lineOffsets = [ ] ;
let currentOffset = 0 ;
const contentLines = [ ] ;
forEachLine ( lineMetadata , ( line , lineIndex , inCode ) => {
2022-06-01 20:23:08 -07:00
lineOffsets [ lineIndex ] = currentOffset ;
if ( ! inCode ) {
2022-08-01 18:48:01 -07:00
line = line . replace ( blockquotePrefixRe , "" ) ;
2022-06-01 20:23:08 -07:00
if ( line . trim ( ) . length === 0 ) {
2022-06-12 18:00:37 -07:00
// Allow RegExp to detect the end of a block
line = "\0" ;
2022-06-01 20:23:08 -07:00
}
contentLines . push ( line ) ;
currentOffset += line . length + 1 ;
}
} ) ;
lineOffsets . push ( currentOffset ) ;
2022-06-02 21:42:48 -07:00
const contentLine = contentLines . join ( " " ) ;
2022-06-01 20:23:08 -07:00
// Determine single-line exclusions for inline code spans
2022-06-02 21:42:48 -07:00
forEachInlineCodeSpan ( contentLine , ( code , lineIndex , columnIndex ) => {
2022-06-01 20:23:08 -07:00
exclusions . push ( [ 0 , columnIndex , code . length ] ) ;
} ) ;
// Identify all link/image reference definitions
2022-06-02 21:42:48 -07:00
forEachLine ( lineMetadata , ( line , lineIndex , inCode ) => {
2022-06-01 20:23:08 -07:00
if ( ! inCode ) {
2022-06-02 21:42:48 -07:00
const linkReferenceDefinitionMatch = linkReferenceDefinitionRe . exec ( line ) ;
2022-06-01 20:23:08 -07:00
if ( linkReferenceDefinitionMatch ) {
2022-06-02 21:42:48 -07:00
const label = normalizeLabel ( linkReferenceDefinitionMatch [ 1 ] ) ;
2022-06-01 20:23:08 -07:00
if ( definitions . has ( label ) ) {
duplicateDefinitions . push ( [ label , lineIndex ] ) ;
}
else {
definitions . set ( label , lineIndex ) ;
}
2022-10-19 21:12:51 -07:00
const labelLength = linkReferenceDefinitionMatch [ 0 ] . length ;
exclusions . push ( [ 0 , lineOffsets [ lineIndex ] , labelLength ] ) ;
2022-06-01 20:23:08 -07:00
}
}
} ) ;
// Identify all link and image references
2022-06-02 21:42:48 -07:00
let lineIndex = 0 ;
const pendingContents = [
2022-06-01 20:23:08 -07:00
{
"content" : contentLine ,
"contentLineIndex" : 0 ,
"contentIndex" : 0 ,
"topLevel" : true
}
] ;
2022-06-02 21:42:48 -07:00
let pendingContent = null ;
2022-06-01 20:23:08 -07:00
while ( ( pendingContent = pendingContents . shift ( ) ) ) {
2022-06-02 21:42:48 -07:00
const { content , contentLineIndex , contentIndex , topLevel } = pendingContent ;
let referenceLinkMatch = null ;
2022-06-01 20:23:08 -07:00
while ( ( referenceLinkMatch = referenceLinkRe . exec ( content ) ) !== null ) {
2022-06-02 21:42:48 -07:00
const [ matchString , matchText , matchLabel ] = referenceLinkMatch ;
2022-06-01 20:23:08 -07:00
if ( ! matchString . startsWith ( "\\" ) &&
! matchString . startsWith ( "!\\" ) &&
! matchText . endsWith ( "\\" ) &&
! ( matchLabel || "" ) . endsWith ( "\\" ) &&
2022-07-30 16:12:27 -07:00
! ( topLevel && excluded ( referenceLinkMatch ) ) ) {
2022-06-02 21:42:48 -07:00
const shortcutLink = ( matchLabel === undefined ) ;
const collapsedLink = ( ! shortcutLink && ( matchLabel . length === 0 ) ) ;
const label = normalizeLabel ( ( shortcutLink || collapsedLink ) ? matchText : matchLabel ) ;
2022-06-01 20:23:08 -07:00
if ( label . length > 0 ) {
2022-07-30 16:12:27 -07:00
const referenceindex = referenceLinkMatch . index ;
if ( topLevel ) {
// Calculate line index
while ( lineOffsets [ lineIndex + 1 ] <= referenceindex ) {
lineIndex ++ ;
}
}
else {
// Use provided line index
lineIndex = contentLineIndex ;
}
const referenceIndex = referenceindex +
( topLevel ? - lineOffsets [ lineIndex ] : contentIndex ) ;
2022-06-01 20:23:08 -07:00
if ( shortcutLink ) {
2022-07-30 16:12:27 -07:00
// Track separately due to ambiguity in "text [text] text"
2022-06-01 20:23:08 -07:00
shortcuts . add ( label ) ;
}
else {
// Track reference and location
2022-06-02 21:42:48 -07:00
const referenceData = references . get ( label ) || [ ] ;
2022-06-01 20:23:08 -07:00
referenceData . push ( [
lineIndex ,
referenceIndex ,
matchString . length
] ) ;
references . set ( label , referenceData ) ;
2022-07-30 16:12:27 -07:00
}
// Check for links embedded in brackets
if ( ! matchString . startsWith ( "!" ) ) {
pendingContents . push ( {
"content" : matchText ,
"contentLineIndex" : lineIndex ,
"contentIndex" : referenceIndex + 1 ,
"topLevel" : false
} ) ;
2022-06-01 20:23:08 -07:00
}
}
}
}
}
return {
2022-06-02 21:42:48 -07:00
references ,
shortcuts ,
definitions ,
duplicateDefinitions
2022-06-01 20:23:08 -07:00
} ;
}
module . exports . getReferenceLinkImageData = getReferenceLinkImageData ;
2020-01-27 19:19:34 -08:00
/ * *
* Gets the most common line ending , falling back to the platform default .
*
* @ param { string } input Markdown content to analyze .
2022-05-06 21:04:34 -07:00
* @ param { Object } [ os ] Node . js "os" module .
2020-01-27 19:19:34 -08:00
* @ returns { string } Preferred line ending .
* /
2022-05-06 21:04:34 -07:00
function getPreferredLineEnding ( input , os ) {
2022-06-02 21:42:48 -07:00
let cr = 0 ;
let lf = 0 ;
let crlf = 0 ;
const endings = input . match ( newLineRe ) || [ ] ;
2022-06-08 22:10:27 -07:00
for ( const ending of endings ) {
2019-10-02 20:10:42 -07:00
// eslint-disable-next-line default-case
switch ( ending ) {
case "\r" :
cr ++ ;
break ;
case "\n" :
lf ++ ;
break ;
case "\r\n" :
crlf ++ ;
break ;
}
2022-06-08 22:10:27 -07:00
}
2022-06-02 21:42:48 -07:00
let preferredLineEnding = null ;
2019-10-02 20:10:42 -07:00
if ( ! cr && ! lf && ! crlf ) {
2022-05-06 21:04:34 -07:00
preferredLineEnding = ( os && os . EOL ) || "\n" ;
2019-10-02 20:10:42 -07:00
}
else if ( ( lf >= crlf ) && ( lf >= cr ) ) {
preferredLineEnding = "\n" ;
}
else if ( crlf >= cr ) {
preferredLineEnding = "\r\n" ;
}
else {
preferredLineEnding = "\r" ;
}
return preferredLineEnding ;
}
module . exports . getPreferredLineEnding = getPreferredLineEnding ;
2020-01-27 19:19:34 -08:00
/ * *
* Normalizes the fields of a RuleOnErrorFixInfo instance .
*
* @ param { Object } fixInfo RuleOnErrorFixInfo instance .
* @ param { number } [ lineNumber ] Line number .
* @ returns { Object } Normalized RuleOnErrorFixInfo instance .
* /
2019-10-02 20:10:42 -07:00
function normalizeFixInfo ( fixInfo , lineNumber ) {
return {
"lineNumber" : fixInfo . lineNumber || lineNumber ,
"editColumn" : fixInfo . editColumn || 1 ,
"deleteCount" : fixInfo . deleteCount || 0 ,
"insertText" : fixInfo . insertText || ""
} ;
}
2020-01-27 19:19:34 -08:00
/ * *
* Fixes the specified error on a line of Markdown content .
*
* @ param { string } line Line of Markdown content .
* @ param { Object } fixInfo RuleOnErrorFixInfo instance .
2022-02-09 22:44:49 -08:00
* @ param { string } [ lineEnding ] Line ending to use .
2022-06-12 17:51:47 -07:00
* @ returns { string | null } Fixed content .
2020-01-27 19:19:34 -08:00
* /
2019-10-02 20:10:42 -07:00
function applyFix ( line , fixInfo , lineEnding ) {
2022-06-02 21:42:48 -07:00
const { editColumn , deleteCount , insertText } = normalizeFixInfo ( fixInfo ) ;
const editIndex = editColumn - 1 ;
2019-10-02 20:10:42 -07:00
return ( deleteCount === - 1 ) ?
null :
line . slice ( 0 , editIndex ) +
insertText . replace ( /\n/g , lineEnding || "\n" ) +
line . slice ( editIndex + deleteCount ) ;
}
module . exports . applyFix = applyFix ;
2022-02-09 22:44:49 -08:00
/ * *
* Applies as many fixes as possible to Markdown content .
*
* @ param { string } input Lines of Markdown content .
* @ param { Object [ ] } errors RuleOnErrorInfo instances .
* @ returns { string } Corrected content .
* /
2022-05-05 23:14:18 -07:00
function applyFixes ( input , errors ) {
2022-08-16 04:01:53 +00:00
const lineEnding = getPreferredLineEnding ( input , _ _webpack _require _ _ ( /*! node:os */ "?0176" ) ) ;
2022-06-02 21:42:48 -07:00
const lines = input . split ( newLineRe ) ;
2019-10-02 20:10:42 -07:00
// Normalize fixInfo objects
2022-06-02 21:42:48 -07:00
let fixInfos = errors
. filter ( ( error ) => error . fixInfo )
. map ( ( error ) => normalizeFixInfo ( error . fixInfo , error . lineNumber ) ) ;
2019-10-02 20:10:42 -07:00
// Sort bottom-to-top, line-deletes last, right-to-left, long-to-short
2022-06-02 21:42:48 -07:00
fixInfos . sort ( ( a , b ) => {
const aDeletingLine = ( a . deleteCount === - 1 ) ;
const bDeletingLine = ( b . deleteCount === - 1 ) ;
2019-10-02 20:10:42 -07:00
return ( ( b . lineNumber - a . lineNumber ) ||
( aDeletingLine ? 1 : ( bDeletingLine ? - 1 : 0 ) ) ||
( b . editColumn - a . editColumn ) ||
( b . insertText . length - a . insertText . length ) ) ;
} ) ;
// Remove duplicate entries (needed for following collapse step)
2022-06-02 21:42:48 -07:00
let lastFixInfo = { } ;
fixInfos = fixInfos . filter ( ( fixInfo ) => {
const unique = ( ( fixInfo . lineNumber !== lastFixInfo . lineNumber ) ||
2019-10-02 20:10:42 -07:00
( fixInfo . editColumn !== lastFixInfo . editColumn ) ||
( fixInfo . deleteCount !== lastFixInfo . deleteCount ) ||
( fixInfo . insertText !== lastFixInfo . insertText ) ) ;
lastFixInfo = fixInfo ;
return unique ;
} ) ;
// Collapse insert/no-delete and no-insert/delete for same line/column
2022-06-08 22:10:27 -07:00
lastFixInfo = {
"lineNumber" : - 1
} ;
for ( const fixInfo of fixInfos ) {
2019-10-02 20:10:42 -07:00
if ( ( fixInfo . lineNumber === lastFixInfo . lineNumber ) &&
( fixInfo . editColumn === lastFixInfo . editColumn ) &&
! fixInfo . insertText &&
( fixInfo . deleteCount > 0 ) &&
lastFixInfo . insertText &&
! lastFixInfo . deleteCount ) {
fixInfo . insertText = lastFixInfo . insertText ;
lastFixInfo . lineNumber = 0 ;
}
lastFixInfo = fixInfo ;
2022-06-08 22:10:27 -07:00
}
2022-06-02 21:42:48 -07:00
fixInfos = fixInfos . filter ( ( fixInfo ) => fixInfo . lineNumber ) ;
2019-10-02 20:10:42 -07:00
// Apply all (remaining/updated) fixes
2022-06-02 21:42:48 -07:00
let lastLineIndex = - 1 ;
let lastEditIndex = - 1 ;
2022-06-08 22:10:27 -07:00
for ( const fixInfo of fixInfos ) {
2022-06-02 21:42:48 -07:00
const { lineNumber , editColumn , deleteCount } = fixInfo ;
const lineIndex = lineNumber - 1 ;
const editIndex = editColumn - 1 ;
2019-10-02 20:10:42 -07:00
if ( ( lineIndex !== lastLineIndex ) ||
2021-02-06 15:49:02 -08:00
( deleteCount === - 1 ) ||
( ( editIndex + deleteCount ) <=
( lastEditIndex - ( ( deleteCount > 0 ) ? 0 : 1 ) ) ) ) {
2022-06-12 18:39:28 -07:00
// @ts-ignore
2019-10-02 20:10:42 -07:00
lines [ lineIndex ] = applyFix ( lines [ lineIndex ] , fixInfo , lineEnding ) ;
}
lastLineIndex = lineIndex ;
lastEditIndex = editIndex ;
2022-06-08 22:10:27 -07:00
}
2019-10-02 20:10:42 -07:00
// Return corrected input
2022-06-02 21:42:48 -07:00
return lines . filter ( ( line ) => line !== null ) . join ( lineEnding ) ;
2022-02-09 22:44:49 -08:00
}
module . exports . applyFixes = applyFixes ;
2021-11-28 23:18:57 -08:00
/ * *
* Gets the range and fixInfo values for reporting an error if the expected
* text is found on the specified line .
*
* @ param { string [ ] } lines Lines of Markdown content .
* @ param { number } lineIndex Line index to check .
* @ param { string } search Text to search for .
* @ param { string } replace Text to replace with .
2022-05-03 21:35:31 -07:00
* @ param { number } [ instance ] Instance on the line ( 1 - based ) .
2021-11-28 23:18:57 -08:00
* @ returns { Object } Range and fixInfo wrapper .
* /
2022-05-03 21:35:31 -07:00
module . exports . getRangeAndFixInfoIfFound =
2022-06-02 21:42:48 -07:00
( lines , lineIndex , search , replace , instance = 1 ) => {
let range = null ;
let fixInfo = null ;
let searchIndex = - 1 ;
2022-05-03 21:35:31 -07:00
while ( instance > 0 ) {
searchIndex = lines [ lineIndex ] . indexOf ( search , searchIndex + 1 ) ;
instance -- ;
}
if ( searchIndex !== - 1 ) {
2022-06-02 21:42:48 -07:00
const column = searchIndex + 1 ;
const length = search . length ;
2022-05-03 21:35:31 -07:00
range = [ column , length ] ;
fixInfo = {
"editColumn" : column ,
"deleteCount" : length ,
"insertText" : replace
} ;
}
return {
2022-06-02 21:42:48 -07:00
range ,
fixInfo
2021-11-28 23:18:57 -08:00
} ;
} ;
/ * *
* Gets the next ( subsequent ) child token if it is of the expected type .
*
* @ param { Object } parentToken Parent token .
* @ param { Object } childToken Child token basis .
* @ param { string } nextType Token type of next token .
* @ param { string } nextNextType Token type of next - next token .
* @ returns { Object } Next token .
* /
function getNextChildToken ( parentToken , childToken , nextType , nextNextType ) {
2022-06-02 21:42:48 -07:00
const { children } = parentToken ;
const index = children . indexOf ( childToken ) ;
2021-11-28 23:18:57 -08:00
if ( ( index !== - 1 ) &&
( children . length > index + 2 ) &&
( children [ index + 1 ] . type === nextType ) &&
( children [ index + 2 ] . type === nextNextType ) ) {
return children [ index + 1 ] ;
}
return null ;
}
module . exports . getNextChildToken = getNextChildToken ;
2022-05-16 22:57:11 -07:00
/ * *
* Expands a path with a tilde to an absolute path .
*
* @ param { string } file Path that may begin with a tilde .
* @ param { Object } os Node . js "os" module .
* @ returns { string } Absolute path ( or original path ) .
* /
function expandTildePath ( file , os ) {
2022-07-24 12:22:32 -07:00
const homedir = os && os . homedir && os . homedir ( ) ;
2022-06-02 21:42:48 -07:00
return homedir ? file . replace ( /^~($|\/|\\)/ , ` ${ homedir } $ 1 ` ) : file ;
2022-05-16 22:57:11 -07:00
}
module . exports . expandTildePath = expandTildePath ;
2019-10-02 20:10:42 -07:00
2021-01-05 20:55:09 -08:00
2022-04-21 21:09:07 -07:00
/***/ } ) ,
/***/ "markdown-it" :
/ * ! * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ! * \
! * * * external "markdownit" * * * !
\ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
/***/ ( ( module ) => {
"use strict" ;
module . exports = markdownit ;
/***/ } ) ,
2022-08-16 04:01:53 +00:00
/***/ "?0176" :
/ * ! * * * * * * * * * * * * * * * * * * * * * * * * * ! * \
! * * * node : os ( ignored ) * * * !
\ * * * * * * * * * * * * * * * * * * * * * * * * * /
2022-05-04 22:09:11 -07:00
/***/ ( ( ) => {
/* (ignored) */
/***/ } ) ,
2022-08-16 04:01:53 +00:00
/***/ "?d0ee" :
/ * ! * * * * * * * * * * * * * * * * * * * * * * * * * ! * \
! * * * node : fs ( ignored ) * * * !
\ * * * * * * * * * * * * * * * * * * * * * * * * * /
2022-04-21 21:09:07 -07:00
/***/ ( ( ) => {
/* (ignored) */
/***/ } ) ,
2022-08-16 04:01:53 +00:00
/***/ "?e6c4" :
/ * ! * * * * * * * * * * * * * * * * * * * * * * * * * ! * \
! * * * node : os ( ignored ) * * * !
\ * * * * * * * * * * * * * * * * * * * * * * * * * /
2022-05-16 22:57:11 -07:00
/***/ ( ( ) => {
/* (ignored) */
/***/ } ) ,
2022-08-16 04:01:53 +00:00
/***/ "?9a52" :
/ * ! * * * * * * * * * * * * * * * * * * * * * * * * * * * ! * \
! * * * node : path ( ignored ) * * * !
\ * * * * * * * * * * * * * * * * * * * * * * * * * * * /
2022-04-21 21:09:07 -07:00
/***/ ( ( ) => {
/* (ignored) */
/***/ } ) ,
2022-08-16 04:01:53 +00:00
/***/ "?39e5" :
/ * ! * * * * * * * * * * * * * * * * * * * * * * * * * * * ! * \
! * * * node : util ( ignored ) * * * !
\ * * * * * * * * * * * * * * * * * * * * * * * * * * * /
2022-04-21 21:09:07 -07:00
/***/ ( ( ) => {
/* (ignored) */
2021-01-05 20:55:09 -08:00
/***/ } ) ,
2021-01-06 19:45:15 -08:00
/***/ "../lib/cache.js" :
/ * ! * * * * * * * * * * * * * * * * * * * * * * * ! * \
! * * * . . / lib / cache . js * * * !
\ * * * * * * * * * * * * * * * * * * * * * * * /
2021-01-05 20:55:09 -08:00
/***/ ( ( module ) => {
2019-10-02 20:10:42 -07:00
"use strict" ;
2021-01-05 20:55:09 -08:00
// @ts-check
2022-06-02 21:42:48 -07:00
const map = new Map ( ) ;
module . exports . set = ( keyValuePairs ) => {
for ( const [ key , value ] of Object . entries ( keyValuePairs ) ) {
2022-06-02 21:33:31 -07:00
map . set ( key , value ) ;
2021-11-23 04:40:05 +00:00
}
2019-10-02 20:10:42 -07:00
} ;
2022-06-02 21:42:48 -07:00
module . exports . clear = ( ) => map . clear ( ) ;
2022-06-02 21:33:31 -07:00
module . exports . codeBlockAndSpanRanges =
2022-06-02 21:42:48 -07:00
( ) => map . get ( "codeBlockAndSpanRanges" ) ;
2022-06-02 21:33:31 -07:00
module . exports . flattenedLists =
2022-06-02 21:42:48 -07:00
( ) => map . get ( "flattenedLists" ) ;
2022-06-02 21:33:31 -07:00
module . exports . htmlElementRanges =
2022-06-02 21:42:48 -07:00
( ) => map . get ( "htmlElementRanges" ) ;
2022-06-02 21:33:31 -07:00
module . exports . lineMetadata =
2022-06-02 21:42:48 -07:00
( ) => map . get ( "lineMetadata" ) ;
2022-06-02 21:33:31 -07:00
module . exports . referenceLinkImageData =
2022-06-02 21:42:48 -07:00
( ) => map . get ( "referenceLinkImageData" ) ;
2019-10-02 20:10:42 -07:00
2021-01-05 20:55:09 -08:00
2021-11-10 21:48:15 -08:00
/***/ } ) ,
/***/ "../lib/constants.js" :
/ * ! * * * * * * * * * * * * * * * * * * * * * * * * * * * ! * \
! * * * . . / lib / constants . js * * * !
\ * * * * * * * * * * * * * * * * * * * * * * * * * * * /
/***/ ( ( module ) => {
"use strict" ;
// @ts-check
2021-11-11 22:37:16 -08:00
module . exports . deprecatedRuleNames = [ "MD002" , "MD006" ] ;
2022-10-29 23:21:45 -07:00
module . exports . fixableRuleNames = [
"MD004" , "MD005" , "MD006" , "MD007" , "MD009" , "MD010" ,
"MD011" , "MD012" , "MD014" , "MD018" , "MD019" , "MD020" ,
"MD021" , "MD022" , "MD023" , "MD026" , "MD027" , "MD030" ,
"MD031" , "MD032" , "MD034" , "MD037" , "MD038" , "MD039" ,
"MD044" , "MD047" , "MD049" , "MD050" , "MD053"
] ;
2021-11-10 21:48:15 -08:00
module . exports . homepage = "https://github.com/DavidAnson/markdownlint" ;
2022-08-08 21:05:50 -07:00
module . exports . version = "0.26.2" ;
2021-11-10 21:48:15 -08:00
2021-01-05 20:55:09 -08:00
/***/ } ) ,
2021-01-06 19:45:15 -08:00
/***/ "../lib/markdownlint.js" :
/ * ! * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ! * \
! * * * . . / lib / markdownlint . js * * * !
\ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
2022-06-02 21:42:48 -07:00
/***/ ( ( module , _ _unused _webpack _exports , _ _webpack _require _ _ ) => {
2021-01-05 20:55:09 -08:00
2019-10-02 20:10:42 -07:00
"use strict" ;
2021-01-05 20:55:09 -08:00
// @ts-check
2022-08-16 04:01:53 +00:00
const path = _ _webpack _require _ _ ( /*! node:path */ "?9a52" ) ;
const { promisify } = _ _webpack _require _ _ ( /*! node:util */ "?39e5" ) ;
2022-06-02 21:42:48 -07:00
const markdownIt = _ _webpack _require _ _ ( /*! markdown-it */ "markdown-it" ) ;
const { deprecatedRuleNames } = _ _webpack _require _ _ ( /*! ./constants */ "../lib/constants.js" ) ;
const rules = _ _webpack _require _ _ ( /*! ./rules */ "../lib/rules.js" ) ;
const helpers = _ _webpack _require _ _ ( /*! ../helpers */ "../helpers/helpers.js" ) ;
const cache = _ _webpack _require _ _ ( /*! ./cache */ "../lib/cache.js" ) ;
2021-02-11 22:16:07 -08:00
// @ts-ignore
// eslint-disable-next-line camelcase, max-len, no-inline-comments, no-undef
2022-06-02 21:42:48 -07:00
const dynamicRequire = ( typeof require === "undefined" ) ? _ _webpack _require _ _ ( "../lib sync recursive" ) : /* c8 ignore next */ require ;
2021-02-11 22:16:07 -08:00
// Capture native require implementation for dynamic loading of modules
2020-01-27 19:19:34 -08:00
/ * *
* Validate the list of rules for structure and reuse .
*
* @ param { Rule [ ] } ruleList List of rules .
2021-12-11 21:44:25 -08:00
* @ param { boolean } synchronous Whether to execute synchronously .
2022-06-11 22:40:45 -07:00
* @ returns { Error | null } Error message if validation fails .
2020-01-27 19:19:34 -08:00
* /
2021-12-11 21:44:25 -08:00
function validateRuleList ( ruleList , synchronous ) {
2022-06-02 21:42:48 -07:00
let result = null ;
2019-10-02 20:10:42 -07:00
if ( ruleList . length === rules . length ) {
// No need to validate if only using built-in rules
return result ;
}
2022-06-02 21:42:48 -07:00
const allIds = { } ;
2022-06-08 22:10:27 -07:00
for ( const [ index , rule ] of ruleList . entries ( ) ) {
2022-06-02 21:42:48 -07:00
const customIndex = index - rules . length ;
2022-06-08 22:10:27 -07:00
// eslint-disable-next-line no-inner-declarations, jsdoc/require-jsdoc
2019-10-02 20:10:42 -07:00
function newError ( property ) {
return new Error ( "Property '" + property + "' of custom rule at index " +
customIndex + " is incorrect." ) ;
}
2022-06-08 22:10:27 -07:00
for ( const property of [ "names" , "tags" ] ) {
2022-06-02 21:42:48 -07:00
const value = rule [ property ] ;
2019-10-02 20:10:42 -07:00
if ( ! result &&
( ! value || ! Array . isArray ( value ) || ( value . length === 0 ) ||
! value . every ( helpers . isString ) || value . some ( helpers . isEmptyString ) ) ) {
result = newError ( property ) ;
}
2022-06-08 22:10:27 -07:00
}
for ( const propertyInfo of [
2019-10-02 20:10:42 -07:00
[ "description" , "string" ] ,
[ "function" , "function" ]
2022-06-08 22:10:27 -07:00
] ) {
2022-06-02 21:42:48 -07:00
const property = propertyInfo [ 0 ] ;
const value = rule [ property ] ;
2019-10-02 20:10:42 -07:00
if ( ! result && ( ! value || ( typeof value !== propertyInfo [ 1 ] ) ) ) {
result = newError ( property ) ;
}
2022-06-08 22:10:27 -07:00
}
2021-02-06 19:55:22 -08:00
if ( ! result &&
rule . information &&
( Object . getPrototypeOf ( rule . information ) !== URL . prototype ) ) {
result = newError ( "information" ) ;
2019-10-02 20:10:42 -07:00
}
2021-12-11 21:44:25 -08:00
if ( ! result &&
( rule . asynchronous !== undefined ) &&
( typeof rule . asynchronous !== "boolean" ) ) {
result = newError ( "asynchronous" ) ;
}
if ( ! result && rule . asynchronous && synchronous ) {
result = new Error ( "Custom rule " + rule . names . join ( "/" ) + " at index " + customIndex +
" is asynchronous and can not be used in a synchronous context." ) ;
}
2019-10-02 20:10:42 -07:00
if ( ! result ) {
2022-06-08 22:10:27 -07:00
for ( const name of rule . names ) {
2022-06-02 21:42:48 -07:00
const nameUpper = name . toUpperCase ( ) ;
2019-10-02 20:10:42 -07:00
if ( ! result && ( allIds [ nameUpper ] !== undefined ) ) {
result = new Error ( "Name '" + name + "' of custom rule at index " +
customIndex + " is already used as a name or tag." ) ;
}
allIds [ nameUpper ] = true ;
2022-06-08 22:10:27 -07:00
}
for ( const tag of rule . tags ) {
2022-06-02 21:42:48 -07:00
const tagUpper = tag . toUpperCase ( ) ;
2019-10-02 20:10:42 -07:00
if ( ! result && allIds [ tagUpper ] ) {
result = new Error ( "Tag '" + tag + "' of custom rule at index " +
customIndex + " is already used as a name." ) ;
}
allIds [ tagUpper ] = false ;
2022-06-08 22:10:27 -07:00
}
2019-10-02 20:10:42 -07:00
}
2022-06-08 22:10:27 -07:00
}
2019-10-02 20:10:42 -07:00
return result ;
}
2020-01-27 19:19:34 -08:00
/ * *
* Creates a LintResults instance with toString for pretty display .
*
* @ param { Rule [ ] } ruleList List of rules .
* @ returns { LintResults } New LintResults instance .
* /
2019-10-02 20:10:42 -07:00
function newResults ( ruleList ) {
2022-06-02 21:42:48 -07:00
const lintResults = { } ;
2020-01-27 19:19:34 -08:00
// eslint-disable-next-line jsdoc/require-jsdoc
2020-09-13 21:15:11 -07:00
function toString ( useAlias ) {
2022-06-02 21:42:48 -07:00
let ruleNameToRule = null ;
const results = [ ] ;
const keys = Object . keys ( lintResults ) ;
2020-09-13 21:15:11 -07:00
keys . sort ( ) ;
2022-06-08 22:10:27 -07:00
for ( const file of keys ) {
2022-06-02 21:42:48 -07:00
const fileResults = lintResults [ file ] ;
2019-10-02 20:10:42 -07:00
if ( Array . isArray ( fileResults ) ) {
2022-06-08 22:10:27 -07:00
for ( const result of fileResults ) {
2022-06-02 21:42:48 -07:00
const ruleMoniker = result . ruleNames ?
2019-10-02 20:10:42 -07:00
result . ruleNames . join ( "/" ) :
( result . ruleName + "/" + result . ruleAlias ) ;
results . push ( file + ": " +
result . lineNumber + ": " +
ruleMoniker + " " +
result . ruleDescription +
( result . errorDetail ?
" [" + result . errorDetail + "]" :
"" ) +
( result . errorContext ?
" [Context: \"" + result . errorContext + "\"]" :
"" ) ) ;
2022-06-08 22:10:27 -07:00
}
2019-10-02 20:10:42 -07:00
}
else {
if ( ! ruleNameToRule ) {
ruleNameToRule = { } ;
2022-06-08 22:10:27 -07:00
for ( const rule of ruleList ) {
2022-06-02 21:42:48 -07:00
const ruleName = rule . names [ 0 ] . toUpperCase ( ) ;
2019-10-02 20:10:42 -07:00
ruleNameToRule [ ruleName ] = rule ;
2022-06-08 22:10:27 -07:00
}
2019-10-02 20:10:42 -07:00
}
2022-06-08 22:10:27 -07:00
for ( const [ ruleName , ruleResults ] of Object . entries ( fileResults ) ) {
2022-06-02 21:42:48 -07:00
const rule = ruleNameToRule [ ruleName . toUpperCase ( ) ] ;
2022-06-08 22:10:27 -07:00
for ( const lineNumber of ruleResults ) {
// @ts-ignore
2022-06-02 21:42:48 -07:00
const nameIndex = Math . min ( useAlias ? 1 : 0 , rule . names . length - 1 ) ;
const result = file + ": " +
2019-10-02 20:10:42 -07:00
lineNumber + ": " +
2022-06-08 22:10:27 -07:00
// @ts-ignore
2019-10-02 20:10:42 -07:00
rule . names [ nameIndex ] + " " +
2022-06-08 22:10:27 -07:00
// @ts-ignore
2019-10-02 20:10:42 -07:00
rule . description ;
results . push ( result ) ;
2022-06-08 22:10:27 -07:00
}
}
2019-10-02 20:10:42 -07:00
}
2022-06-08 22:10:27 -07:00
}
2019-10-02 20:10:42 -07:00
return results . join ( "\n" ) ;
2020-09-13 21:15:11 -07:00
}
Object . defineProperty ( lintResults , "toString" , { "value" : toString } ) ;
2020-01-27 19:19:34 -08:00
// @ts-ignore
2020-09-13 21:15:11 -07:00
return lintResults ;
2019-10-02 20:10:42 -07:00
}
2020-01-27 19:19:34 -08:00
/ * *
* Remove front matter ( if present at beginning of content ) .
*
* @ param { string } content Markdown content .
* @ param { RegExp } frontMatter Regular expression to match front matter .
* @ returns { Object } Trimmed content and front matter lines .
* /
2019-10-02 20:10:42 -07:00
function removeFrontMatter ( content , frontMatter ) {
2022-06-02 21:42:48 -07:00
let frontMatterLines = [ ] ;
2019-10-02 20:10:42 -07:00
if ( frontMatter ) {
2022-06-02 21:42:48 -07:00
const frontMatterMatch = content . match ( frontMatter ) ;
2019-10-02 20:10:42 -07:00
if ( frontMatterMatch && ! frontMatterMatch . index ) {
2022-06-02 21:42:48 -07:00
const contentMatched = frontMatterMatch [ 0 ] ;
2019-10-02 20:10:42 -07:00
content = content . slice ( contentMatched . length ) ;
frontMatterLines = contentMatched . split ( helpers . newLineRe ) ;
2020-09-13 21:15:11 -07:00
if ( ( frontMatterLines . length > 0 ) &&
2019-10-02 20:10:42 -07:00
( frontMatterLines [ frontMatterLines . length - 1 ] === "" ) ) {
frontMatterLines . length -- ;
}
}
}
return {
"content" : content ,
"frontMatterLines" : frontMatterLines
} ;
}
2020-01-27 19:19:34 -08:00
/ * *
2022-06-09 23:56:44 -07:00
* Freeze all freeze - able members of a token and its children .
*
* @ param { MarkdownItToken } token A markdown - it token .
* @ returns { void }
* /
function freezeToken ( token ) {
if ( token . attrs ) {
for ( const attr of token . attrs ) {
Object . freeze ( attr ) ;
}
Object . freeze ( token . attrs ) ;
}
if ( token . children ) {
for ( const child of token . children ) {
freezeToken ( child ) ;
}
Object . freeze ( token . children ) ;
}
if ( token . map ) {
Object . freeze ( token . map ) ;
}
Object . freeze ( token ) ;
}
/ * *
* Annotate tokens with line / lineNumber and freeze them .
2020-01-27 19:19:34 -08:00
*
* @ param { MarkdownItToken [ ] } tokens Array of markdown - it tokens .
* @ param { string [ ] } lines Lines of Markdown content .
* @ returns { void }
* /
2022-06-09 23:56:44 -07:00
function annotateAndFreezeTokens ( tokens , lines ) {
2022-06-02 21:42:48 -07:00
let trMap = null ;
2022-06-08 22:10:27 -07:00
for ( const token of tokens ) {
2021-11-26 04:26:15 +00:00
// Provide missing maps for table content
if ( token . type === "tr_open" ) {
trMap = token . map ;
2019-10-02 20:10:42 -07:00
}
2021-11-26 04:26:15 +00:00
else if ( token . type === "tr_close" ) {
trMap = null ;
2019-10-02 20:10:42 -07:00
}
2021-11-26 04:26:15 +00:00
if ( ! token . map && trMap ) {
2022-06-02 21:42:48 -07:00
token . map = [ ... trMap ] ;
2019-10-02 20:10:42 -07:00
}
// Update token metadata
if ( token . map ) {
token . line = lines [ token . map [ 0 ] ] ;
token . lineNumber = token . map [ 0 ] + 1 ;
// Trim bottom of token to exclude whitespace lines
while ( token . map [ 1 ] && ! ( ( lines [ token . map [ 1 ] - 1 ] || "" ) . trim ( ) ) ) {
token . map [ 1 ] -- ;
}
2022-06-09 23:56:44 -07:00
}
// Annotate children with lineNumber
if ( token . children ) {
2022-06-02 21:42:48 -07:00
const codeSpanExtraLines = [ ] ;
2022-06-17 05:29:12 +00:00
if ( token . children . some ( ( child ) => child . type === "code_inline" ) ) {
helpers . forEachInlineCodeSpan ( token . content , ( code ) => {
codeSpanExtraLines . push ( code . split ( helpers . newLineRe ) . length - 1 ) ;
} ) ;
}
let lineNumber = token . lineNumber ;
2022-06-09 23:56:44 -07:00
for ( const child of token . children ) {
2022-06-02 21:42:48 -07:00
child . lineNumber = lineNumber ;
child . line = lines [ lineNumber - 1 ] ;
2019-10-02 20:10:42 -07:00
if ( ( child . type === "softbreak" ) || ( child . type === "hardbreak" ) ) {
2022-06-02 21:42:48 -07:00
lineNumber ++ ;
2019-10-02 20:10:42 -07:00
}
else if ( child . type === "code_inline" ) {
2022-06-02 21:42:48 -07:00
lineNumber += codeSpanExtraLines . shift ( ) ;
2019-10-02 20:10:42 -07:00
}
2022-06-08 22:10:27 -07:00
}
2019-10-02 20:10:42 -07:00
}
2022-06-09 23:56:44 -07:00
freezeToken ( token ) ;
2022-06-08 22:10:27 -07:00
}
2022-06-09 23:56:44 -07:00
Object . freeze ( tokens ) ;
2019-10-02 20:10:42 -07:00
}
2020-01-27 19:19:34 -08:00
/ * *
* Map rule names / tags to canonical rule name .
*
* @ param { Rule [ ] } ruleList List of rules .
* @ returns { Object . < string , string [ ] > } Map of alias to rule name .
* /
2019-10-02 20:10:42 -07:00
function mapAliasToRuleNames ( ruleList ) {
2022-06-02 21:42:48 -07:00
const aliasToRuleNames = { } ;
2019-10-02 20:10:42 -07:00
// const tagToRuleNames = {};
2022-06-08 22:10:27 -07:00
for ( const rule of ruleList ) {
2022-06-02 21:42:48 -07:00
const ruleName = rule . names [ 0 ] . toUpperCase ( ) ;
2019-10-02 20:10:42 -07:00
// The following is useful for updating README.md:
// console.log(
// "* **[" + ruleName + "](doc/Rules.md#" + ruleName.toLowerCase() +
// ")** *" + rule.names.slice(1).join("/") + "* - " + rule.description);
2022-06-08 22:10:27 -07:00
for ( const name of rule . names ) {
2022-06-02 21:42:48 -07:00
const nameUpper = name . toUpperCase ( ) ;
2019-10-02 20:10:42 -07:00
aliasToRuleNames [ nameUpper ] = [ ruleName ] ;
2022-06-08 22:10:27 -07:00
}
for ( const tag of rule . tags ) {
2022-06-02 21:42:48 -07:00
const tagUpper = tag . toUpperCase ( ) ;
const ruleNames = aliasToRuleNames [ tagUpper ] || [ ] ;
2019-10-02 20:10:42 -07:00
ruleNames . push ( ruleName ) ;
aliasToRuleNames [ tagUpper ] = ruleNames ;
// tagToRuleNames[tag] = ruleName;
2022-06-08 22:10:27 -07:00
}
}
2019-10-02 20:10:42 -07:00
// The following is useful for updating README.md:
// Object.keys(tagToRuleNames).sort().forEach(function forTag(tag) {
// console.log("* **" + tag + "** - " +
// aliasToRuleNames[tag.toUpperCase()].join(", "));
// });
2020-01-27 19:19:34 -08:00
// @ts-ignore
2019-10-02 20:10:42 -07:00
return aliasToRuleNames ;
}
2020-01-27 19:19:34 -08:00
/ * *
* Apply ( and normalize ) configuration object .
*
* @ param { Rule [ ] } ruleList List of rules .
* @ param { Configuration } config Configuration object .
* @ param { Object . < string , string [ ] > } aliasToRuleNames Map of alias to rule
* names .
* @ returns { Configuration } Effective configuration .
* /
2019-10-02 20:10:42 -07:00
function getEffectiveConfig ( ruleList , config , aliasToRuleNames ) {
2022-06-02 21:42:48 -07:00
const defaultKey = Object . keys ( config ) . filter ( ( key ) => key . toUpperCase ( ) === "DEFAULT" ) ;
const ruleDefault = ( defaultKey . length === 0 ) || ! ! config [ defaultKey [ 0 ] ] ;
const effectiveConfig = { } ;
2022-06-08 22:10:27 -07:00
for ( const rule of ruleList ) {
2022-06-02 21:42:48 -07:00
const ruleName = rule . names [ 0 ] . toUpperCase ( ) ;
2019-10-02 20:10:42 -07:00
effectiveConfig [ ruleName ] = ruleDefault ;
2022-06-08 22:10:27 -07:00
}
for ( const ruleName of deprecatedRuleNames ) {
2019-10-02 20:10:42 -07:00
effectiveConfig [ ruleName ] = false ;
2022-06-08 22:10:27 -07:00
}
for ( const key of Object . keys ( config ) ) {
2022-06-02 21:42:48 -07:00
let value = config [ key ] ;
2019-10-02 20:10:42 -07:00
if ( value ) {
if ( ! ( value instanceof Object ) ) {
value = { } ;
}
}
else {
value = false ;
}
2022-06-02 21:42:48 -07:00
const keyUpper = key . toUpperCase ( ) ;
2022-06-08 22:10:27 -07:00
for ( const ruleName of ( aliasToRuleNames [ keyUpper ] || [ ] ) ) {
2019-10-02 20:10:42 -07:00
effectiveConfig [ ruleName ] = value ;
2022-06-08 22:10:27 -07:00
}
}
2019-10-02 20:10:42 -07:00
return effectiveConfig ;
}
2022-06-05 22:32:22 -07:00
/ * *
* Parse the content of a configuration file .
*
* @ param { string } name Name of the configuration file .
* @ param { string } content Configuration content .
2022-06-11 22:40:45 -07:00
* @ param { ConfigurationParser [ ] | null } [ parsers ] Parsing function ( s ) .
2022-06-05 22:32:22 -07:00
* @ returns { Object } Configuration object and error message .
* /
function parseConfiguration ( name , content , parsers ) {
let config = null ;
let message = "" ;
const errors = [ ] ;
let index = 0 ;
// Try each parser
( parsers || [ JSON . parse ] ) . every ( ( parser ) => {
try {
config = parser ( content ) ;
}
catch ( error ) {
errors . push ( ` Parser ${ index ++ } : ${ error . message } ` ) ;
}
return ! config ;
} ) ;
// Message if unable to parse
if ( ! config ) {
errors . unshift ( ` Unable to parse ' ${ name } ' ` ) ;
message = errors . join ( "; " ) ;
}
return {
config ,
message
} ;
}
2020-01-27 19:19:34 -08:00
/ * *
* Create a mapping of enabled rules per line .
*
* @ param { Rule [ ] } ruleList List of rules .
* @ param { string [ ] } lines List of content lines .
* @ param { string [ ] } frontMatterLines List of front matter lines .
* @ param { boolean } noInlineConfig Whether to allow inline configuration .
2020-04-11 13:54:46 -07:00
* @ param { Configuration } config Configuration object .
2022-06-11 22:40:45 -07:00
* @ param { ConfigurationParser [ ] | null } configParsers Configuration parsers .
2020-01-27 19:19:34 -08:00
* @ param { Object . < string , string [ ] > } aliasToRuleNames Map of alias to rule
* names .
2020-04-11 13:54:46 -07:00
* @ returns { Object } Effective configuration and enabled rules per line number .
2020-01-27 19:19:34 -08:00
* /
2022-06-05 22:32:22 -07:00
function getEnabledRulesPerLineNumber ( ruleList , lines , frontMatterLines , noInlineConfig , config , configParsers , aliasToRuleNames ) {
2020-04-11 13:54:46 -07:00
// Shared variables
2022-06-02 21:42:48 -07:00
let enabledRules = { } ;
let capturedRules = { } ;
const allRuleNames = [ ] ;
const enabledRulesPerLineNumber = new Array ( 1 + frontMatterLines . length ) ;
2020-04-11 13:54:46 -07:00
// Helper functions
2020-01-27 19:19:34 -08:00
// eslint-disable-next-line jsdoc/require-jsdoc
2021-12-21 21:31:47 -08:00
function handleInlineConfig ( input , forEachMatch , forEachLine ) {
2022-06-08 22:10:27 -07:00
for ( const [ lineIndex , line ] of input . entries ( ) ) {
2020-04-11 13:54:46 -07:00
if ( ! noInlineConfig ) {
2022-06-02 21:42:48 -07:00
let match = null ;
2022-02-12 17:46:46 -08:00
while ( ( match = helpers . inlineCommentStartRe . exec ( line ) ) ) {
2022-06-02 21:42:48 -07:00
const action = match [ 2 ] . toUpperCase ( ) ;
const startIndex = match . index + match [ 1 ] . length ;
const endIndex = line . indexOf ( "-->" , startIndex ) ;
2022-02-12 17:46:46 -08:00
if ( endIndex === - 1 ) {
break ;
}
2022-06-02 21:42:48 -07:00
const parameter = line . slice ( startIndex , endIndex ) ;
2020-11-24 16:37:11 -08:00
forEachMatch ( action , parameter , lineIndex + 1 ) ;
2020-04-11 13:54:46 -07:00
}
2019-12-14 13:50:48 -08:00
}
2020-04-11 13:54:46 -07:00
if ( forEachLine ) {
forEachLine ( ) ;
2019-12-14 13:50:48 -08:00
}
2022-06-08 22:10:27 -07:00
}
2019-10-02 20:10:42 -07:00
}
2020-04-11 13:54:46 -07:00
// eslint-disable-next-line jsdoc/require-jsdoc
function configureFile ( action , parameter ) {
if ( action === "CONFIGURE-FILE" ) {
2022-06-05 22:32:22 -07:00
const { "config" : parsed } = parseConfiguration ( "CONFIGURE-FILE" , parameter , configParsers ) ;
if ( parsed ) {
config = Object . assign ( Object . assign ( { } , config ) , parsed ) ;
2019-12-14 13:50:48 -08:00
}
2020-04-11 13:54:46 -07:00
}
}
// eslint-disable-next-line jsdoc/require-jsdoc
2020-11-24 16:37:11 -08:00
function applyEnableDisable ( action , parameter , state ) {
2022-06-02 21:42:48 -07:00
state = Object . assign ( { } , state ) ;
const enabled = ( action . startsWith ( "ENABLE" ) ) ;
const trimmed = parameter && parameter . trim ( ) ;
const items = trimmed ? trimmed . toUpperCase ( ) . split ( /\s+/ ) : allRuleNames ;
2022-06-08 22:10:27 -07:00
for ( const nameUpper of items ) {
for ( const ruleName of ( aliasToRuleNames [ nameUpper ] || [ ] ) ) {
2020-11-24 16:37:11 -08:00
state [ ruleName ] = enabled ;
2022-06-08 22:10:27 -07:00
}
}
2021-12-21 21:31:47 -08:00
return state ;
2020-04-11 13:54:46 -07:00
}
// eslint-disable-next-line jsdoc/require-jsdoc
function enableDisableFile ( action , parameter ) {
if ( ( action === "ENABLE-FILE" ) || ( action === "DISABLE-FILE" ) ) {
2021-12-21 21:31:47 -08:00
enabledRules = applyEnableDisable ( action , parameter , enabledRules ) ;
2020-04-11 13:54:46 -07:00
}
}
// eslint-disable-next-line jsdoc/require-jsdoc
function captureRestoreEnableDisable ( action , parameter ) {
if ( action === "CAPTURE" ) {
2021-12-21 21:31:47 -08:00
capturedRules = enabledRules ;
2020-04-11 13:54:46 -07:00
}
else if ( action === "RESTORE" ) {
2021-12-21 21:31:47 -08:00
enabledRules = capturedRules ;
2020-04-11 13:54:46 -07:00
}
else if ( ( action === "ENABLE" ) || ( action === "DISABLE" ) ) {
2021-12-21 21:31:47 -08:00
enabledRules = applyEnableDisable ( action , parameter , enabledRules ) ;
2020-04-11 13:54:46 -07:00
}
}
// eslint-disable-next-line jsdoc/require-jsdoc
function updateLineState ( ) {
2021-12-21 21:31:47 -08:00
enabledRulesPerLineNumber . push ( enabledRules ) ;
2020-11-24 16:37:11 -08:00
}
// eslint-disable-next-line jsdoc/require-jsdoc
2022-05-15 15:59:11 -07:00
function disableLineNextLine ( action , parameter , lineNumber ) {
2022-06-02 21:42:48 -07:00
const disableLine = ( action === "DISABLE-LINE" ) ;
const disableNextLine = ( action === "DISABLE-NEXT-LINE" ) ;
2022-05-15 15:59:11 -07:00
if ( disableLine || disableNextLine ) {
2022-06-02 21:42:48 -07:00
const nextLineNumber = frontMatterLines . length + lineNumber + ( disableNextLine ? 1 : 0 ) ;
2021-12-19 00:41:08 -05:00
enabledRulesPerLineNumber [ nextLineNumber ] =
applyEnableDisable ( action , parameter , enabledRulesPerLineNumber [ nextLineNumber ] || { } ) ;
2020-11-24 16:37:11 -08:00
}
2020-04-11 13:54:46 -07:00
}
// Handle inline comments
2021-12-21 21:31:47 -08:00
handleInlineConfig ( [ lines . join ( "\n" ) ] , configureFile ) ;
2022-06-02 21:42:48 -07:00
const effectiveConfig = getEffectiveConfig ( ruleList , config , aliasToRuleNames ) ;
2022-06-08 22:10:27 -07:00
for ( const rule of ruleList ) {
2022-06-02 21:42:48 -07:00
const ruleName = rule . names [ 0 ] . toUpperCase ( ) ;
2020-04-11 13:54:46 -07:00
allRuleNames . push ( ruleName ) ;
enabledRules [ ruleName ] = ! ! effectiveConfig [ ruleName ] ;
2022-06-08 22:10:27 -07:00
}
2020-04-11 13:54:46 -07:00
capturedRules = enabledRules ;
2021-12-21 21:31:47 -08:00
handleInlineConfig ( lines , enableDisableFile ) ;
handleInlineConfig ( lines , captureRestoreEnableDisable , updateLineState ) ;
2022-05-15 15:59:11 -07:00
handleInlineConfig ( lines , disableLineNextLine ) ;
2020-04-11 13:54:46 -07:00
// Return results
return {
2022-06-02 21:42:48 -07:00
effectiveConfig ,
enabledRulesPerLineNumber
2020-04-11 13:54:46 -07:00
} ;
2019-10-02 20:10:42 -07:00
}
2020-01-27 19:19:34 -08:00
/ * *
* Lints a string containing Markdown content .
*
* @ param { Rule [ ] } ruleList List of rules .
* @ param { string } name Identifier for the content .
2020-11-24 16:37:11 -08:00
* @ param { string } content Markdown content .
* @ param { Object } md Instance of markdown - it .
2020-01-27 19:19:34 -08:00
* @ param { Configuration } config Configuration object .
2022-06-11 22:40:45 -07:00
* @ param { ConfigurationParser [ ] | null } configParsers Configuration parsers .
2020-01-27 19:19:34 -08:00
* @ param { RegExp } frontMatter Regular expression for front matter .
* @ param { boolean } handleRuleFailures Whether to handle exceptions in rules .
* @ param { boolean } noInlineConfig Whether to allow inline configuration .
* @ param { number } resultVersion Version of the LintResults object to return .
* @ param { Function } callback Callback ( err , result ) function .
* @ returns { void }
* /
2022-06-05 22:32:22 -07:00
function lintContent ( ruleList , name , content , md , config , configParsers , frontMatter , handleRuleFailures , noInlineConfig , resultVersion , callback ) {
2019-10-02 20:10:42 -07:00
// Remove UTF-8 byte order marker (if present)
2020-09-13 21:15:11 -07:00
content = content . replace ( /^\uFEFF/ , "" ) ;
2019-10-02 20:10:42 -07:00
// Remove front matter
2022-06-02 21:42:48 -07:00
const removeFrontMatterResult = removeFrontMatter ( content , frontMatter ) ;
2022-06-04 22:59:19 -07:00
const { frontMatterLines } = removeFrontMatterResult ;
content = removeFrontMatterResult . content ;
// Get enabled rules per line (with HTML comments present)
2022-06-05 22:32:22 -07:00
const { effectiveConfig , enabledRulesPerLineNumber } = getEnabledRulesPerLineNumber ( ruleList , content . split ( helpers . newLineRe ) , frontMatterLines , noInlineConfig , config , configParsers , mapAliasToRuleNames ( ruleList ) ) ;
2022-06-04 22:59:19 -07:00
// Hide the content of HTML comments from rules, etc.
content = helpers . clearHtmlCommentText ( content ) ;
2019-10-02 20:10:42 -07:00
// Parse content into tokens and lines
2022-06-02 21:42:48 -07:00
const tokens = md . parse ( content , { } ) ;
const lines = content . split ( helpers . newLineRe ) ;
2022-06-09 23:56:44 -07:00
annotateAndFreezeTokens ( tokens , lines ) ;
// Create (frozen) parameters for rules
const paramsBase = {
2022-06-02 21:42:48 -07:00
name ,
tokens ,
2022-06-09 23:56:44 -07:00
"lines" : Object . freeze ( lines ) ,
"frontMatterLines" : Object . freeze ( frontMatterLines )
} ;
2022-06-02 21:42:48 -07:00
const lineMetadata = helpers . getLineMetadata ( paramsBase ) ;
const codeBlockAndSpanRanges = helpers . codeBlockAndSpanRanges ( paramsBase , lineMetadata ) ;
const flattenedLists = helpers . flattenLists ( paramsBase . tokens ) ;
const htmlElementRanges = helpers . htmlElementRanges ( paramsBase , lineMetadata ) ;
2022-06-12 18:39:28 -07:00
const referenceLinkImageData = helpers . getReferenceLinkImageData ( lineMetadata ) ;
2022-06-02 21:33:31 -07:00
cache . set ( {
2022-06-02 21:42:48 -07:00
codeBlockAndSpanRanges ,
flattenedLists ,
htmlElementRanges ,
lineMetadata ,
referenceLinkImageData
2022-06-02 21:33:31 -07:00
} ) ;
2019-10-02 20:10:42 -07:00
// Function to run for each rule
2022-06-02 21:42:48 -07:00
let results = [ ] ;
2020-01-27 19:19:34 -08:00
// eslint-disable-next-line jsdoc/require-jsdoc
2019-10-02 20:10:42 -07:00
function forRule ( rule ) {
// Configure rule
2022-06-02 21:42:48 -07:00
const ruleName = rule . names [ 0 ] . toUpperCase ( ) ;
const params = Object . assign ( Object . assign ( { } , paramsBase ) , { "config" : effectiveConfig [ ruleName ] } ) ;
2020-01-27 19:19:34 -08:00
// eslint-disable-next-line jsdoc/require-jsdoc
2019-10-02 20:10:42 -07:00
function throwError ( property ) {
throw new Error ( "Property '" + property + "' of onError parameter is incorrect." ) ;
}
2020-01-27 19:19:34 -08:00
// eslint-disable-next-line jsdoc/require-jsdoc
2019-10-02 20:10:42 -07:00
function onError ( errorInfo ) {
if ( ! errorInfo ||
! helpers . isNumber ( errorInfo . lineNumber ) ||
( errorInfo . lineNumber < 1 ) ||
( errorInfo . lineNumber > lines . length ) ) {
throwError ( "lineNumber" ) ;
}
2022-06-02 21:42:48 -07:00
const lineNumber = errorInfo . lineNumber + frontMatterLines . length ;
2021-12-04 22:09:20 -08:00
if ( ! enabledRulesPerLineNumber [ lineNumber ] [ ruleName ] ) {
return ;
}
2019-10-02 20:10:42 -07:00
if ( errorInfo . detail &&
! helpers . isString ( errorInfo . detail ) ) {
throwError ( "detail" ) ;
}
if ( errorInfo . context &&
! helpers . isString ( errorInfo . context ) ) {
throwError ( "context" ) ;
}
if ( errorInfo . range &&
( ! Array . isArray ( errorInfo . range ) ||
( errorInfo . range . length !== 2 ) ||
! helpers . isNumber ( errorInfo . range [ 0 ] ) ||
( errorInfo . range [ 0 ] < 1 ) ||
! helpers . isNumber ( errorInfo . range [ 1 ] ) ||
( errorInfo . range [ 1 ] < 1 ) ||
( ( errorInfo . range [ 0 ] + errorInfo . range [ 1 ] - 1 ) >
lines [ errorInfo . lineNumber - 1 ] . length ) ) ) {
throwError ( "range" ) ;
}
2022-06-02 21:42:48 -07:00
const fixInfo = errorInfo . fixInfo ;
const cleanFixInfo = { } ;
2019-10-02 20:10:42 -07:00
if ( fixInfo ) {
if ( ! helpers . isObject ( fixInfo ) ) {
throwError ( "fixInfo" ) ;
}
2019-10-19 17:55:10 -07:00
if ( fixInfo . lineNumber !== undefined ) {
if ( ( ! helpers . isNumber ( fixInfo . lineNumber ) ||
2019-10-02 20:10:42 -07:00
( fixInfo . lineNumber < 1 ) ||
( fixInfo . lineNumber > lines . length ) ) ) {
2019-10-19 17:55:10 -07:00
throwError ( "fixInfo.lineNumber" ) ;
}
cleanFixInfo . lineNumber =
fixInfo . lineNumber + frontMatterLines . length ;
2019-10-02 20:10:42 -07:00
}
2022-06-02 21:42:48 -07:00
const effectiveLineNumber = fixInfo . lineNumber || errorInfo . lineNumber ;
2019-10-19 17:55:10 -07:00
if ( fixInfo . editColumn !== undefined ) {
if ( ( ! helpers . isNumber ( fixInfo . editColumn ) ||
2019-10-02 20:10:42 -07:00
( fixInfo . editColumn < 1 ) ||
( fixInfo . editColumn >
lines [ effectiveLineNumber - 1 ] . length + 1 ) ) ) {
2019-10-19 17:55:10 -07:00
throwError ( "fixInfo.editColumn" ) ;
}
cleanFixInfo . editColumn = fixInfo . editColumn ;
2019-10-02 20:10:42 -07:00
}
2019-10-19 17:55:10 -07:00
if ( fixInfo . deleteCount !== undefined ) {
if ( ( ! helpers . isNumber ( fixInfo . deleteCount ) ||
2019-10-02 20:10:42 -07:00
( fixInfo . deleteCount < - 1 ) ||
( fixInfo . deleteCount >
lines [ effectiveLineNumber - 1 ] . length ) ) ) {
2019-10-19 17:55:10 -07:00
throwError ( "fixInfo.deleteCount" ) ;
}
cleanFixInfo . deleteCount = fixInfo . deleteCount ;
2019-10-02 20:10:42 -07:00
}
2019-10-19 17:55:10 -07:00
if ( fixInfo . insertText !== undefined ) {
if ( ! helpers . isString ( fixInfo . insertText ) ) {
throwError ( "fixInfo.insertText" ) ;
}
cleanFixInfo . insertText = fixInfo . insertText ;
2019-10-02 20:10:42 -07:00
}
}
2021-12-04 22:09:20 -08:00
results . push ( {
2022-06-02 21:42:48 -07:00
lineNumber ,
2021-12-04 22:09:20 -08:00
"ruleName" : rule . names [ 0 ] ,
"ruleNames" : rule . names ,
"ruleDescription" : rule . description ,
"ruleInformation" : rule . information ? rule . information . href : null ,
"errorDetail" : errorInfo . detail || null ,
"errorContext" : errorInfo . context || null ,
2022-06-02 21:42:48 -07:00
"errorRange" : errorInfo . range ? [ ... errorInfo . range ] : null ,
2019-10-19 17:55:10 -07:00
"fixInfo" : fixInfo ? cleanFixInfo : null
2019-10-02 20:10:42 -07:00
} ) ;
}
2021-12-04 17:02:11 -08:00
// Call (possibly external) rule function to report errors
2022-06-02 21:42:48 -07:00
const catchCallsOnError = ( error ) => onError ( {
2021-12-11 21:44:25 -08:00
"lineNumber" : 1 ,
2022-06-02 21:42:48 -07:00
"detail" : ` This rule threw an exception: ${ error . message || error } `
} ) ;
const invokeRuleFunction = ( ) => rule . function ( params , onError ) ;
2021-12-11 21:44:25 -08:00
if ( rule . asynchronous ) {
// Asynchronous rule, ensure it returns a Promise
2022-06-02 21:42:48 -07:00
const ruleFunctionPromise = Promise . resolve ( ) . then ( invokeRuleFunction ) ;
2021-12-11 21:44:25 -08:00
return handleRuleFailures ?
ruleFunctionPromise . catch ( catchCallsOnError ) :
ruleFunctionPromise ;
}
// Synchronous rule
try {
invokeRuleFunction ( ) ;
}
catch ( error ) {
if ( handleRuleFailures ) {
catchCallsOnError ( error ) ;
2019-10-02 20:10:42 -07:00
}
2021-12-11 21:44:25 -08:00
else {
throw error ;
}
}
return null ;
}
// eslint-disable-next-line jsdoc/require-jsdoc
function formatResults ( ) {
// Sort results by rule name by line number
2022-06-02 21:42:48 -07:00
results . sort ( ( a , b ) => ( a . ruleName . localeCompare ( b . ruleName ) ||
a . lineNumber - b . lineNumber ) ) ;
2021-12-11 21:44:25 -08:00
if ( resultVersion < 3 ) {
// Remove fixInfo and multiple errors for the same rule and line number
2022-06-02 21:42:48 -07:00
const noPrevious = {
2021-12-11 21:44:25 -08:00
"ruleName" : null ,
"lineNumber" : - 1
} ;
2022-06-02 21:42:48 -07:00
results = results . filter ( ( error , index , array ) => {
2021-12-11 21:44:25 -08:00
delete error . fixInfo ;
2022-06-02 21:42:48 -07:00
const previous = array [ index - 1 ] || noPrevious ;
2021-12-11 21:44:25 -08:00
return ( ( error . ruleName !== previous . ruleName ) ||
( error . lineNumber !== previous . lineNumber ) ) ;
} ) ;
}
if ( resultVersion === 0 ) {
// Return a dictionary of rule->[line numbers]
2022-06-02 21:42:48 -07:00
const dictionary = { } ;
for ( const error of results ) {
const ruleLines = dictionary [ error . ruleName ] || [ ] ;
2021-12-11 21:44:25 -08:00
ruleLines . push ( error . lineNumber ) ;
dictionary [ error . ruleName ] = ruleLines ;
}
// @ts-ignore
results = dictionary ;
}
else if ( resultVersion === 1 ) {
// Use ruleAlias instead of ruleNames
2022-06-02 21:42:48 -07:00
for ( const error of results ) {
2021-12-11 21:44:25 -08:00
error . ruleAlias = error . ruleNames [ 1 ] || error . ruleName ;
delete error . ruleNames ;
2019-10-02 20:10:42 -07:00
}
}
else {
2021-12-11 21:44:25 -08:00
// resultVersion 2 or 3: Remove unwanted ruleName
2022-06-02 21:42:48 -07:00
for ( const error of results ) {
2021-12-11 21:44:25 -08:00
delete error . ruleName ;
}
2019-10-02 20:10:42 -07:00
}
2021-12-11 21:44:25 -08:00
return results ;
2019-10-02 20:10:42 -07:00
}
// Run all rules
2022-06-02 21:42:48 -07:00
const ruleListAsync = ruleList . filter ( ( rule ) => rule . asynchronous ) ;
const ruleListSync = ruleList . filter ( ( rule ) => ! rule . asynchronous ) ;
const ruleListAsyncFirst = [
... ruleListAsync ,
... ruleListSync
] ;
const callbackSuccess = ( ) => callback ( null , formatResults ( ) ) ;
const callbackError = ( error ) => callback ( error instanceof Error ? error : new Error ( error ) ) ;
2019-10-02 20:10:42 -07:00
try {
2022-06-02 21:42:48 -07:00
const ruleResults = ruleListAsyncFirst . map ( forRule ) ;
2021-12-11 21:44:25 -08:00
if ( ruleListAsync . length > 0 ) {
Promise . all ( ruleResults . slice ( 0 , ruleListAsync . length ) )
. then ( callbackSuccess )
. catch ( callbackError ) ;
}
else {
callbackSuccess ( ) ;
}
2019-10-02 20:10:42 -07:00
}
2020-09-13 21:15:11 -07:00
catch ( error ) {
2021-12-11 21:44:25 -08:00
callbackError ( error ) ;
2021-12-04 17:02:11 -08:00
}
2021-12-11 21:44:25 -08:00
finally {
cache . clear ( ) ;
2021-12-04 17:02:11 -08:00
}
2019-10-02 20:10:42 -07:00
}
2020-01-27 19:19:34 -08:00
/ * *
* Lints a file containing Markdown content .
*
* @ param { Rule [ ] } ruleList List of rules .
* @ param { string } file Path of file to lint .
2020-11-24 16:37:11 -08:00
* @ param { Object } md Instance of markdown - it .
2020-01-27 19:19:34 -08:00
* @ param { Configuration } config Configuration object .
2022-06-11 22:40:45 -07:00
* @ param { ConfigurationParser [ ] | null } configParsers Configuration parsers .
2020-01-27 19:19:34 -08:00
* @ param { RegExp } frontMatter Regular expression for front matter .
* @ param { boolean } handleRuleFailures Whether to handle exceptions in rules .
* @ param { boolean } noInlineConfig Whether to allow inline configuration .
* @ param { number } resultVersion Version of the LintResults object to return .
2021-08-12 19:38:03 -07:00
* @ param { Object } fs File system implementation .
2020-01-27 19:19:34 -08:00
* @ param { boolean } synchronous Whether to execute synchronously .
* @ param { Function } callback Callback ( err , result ) function .
* @ returns { void }
* /
2022-06-05 22:32:22 -07:00
function lintFile ( ruleList , file , md , config , configParsers , frontMatter , handleRuleFailures , noInlineConfig , resultVersion , fs , synchronous , callback ) {
2020-01-27 19:19:34 -08:00
// eslint-disable-next-line jsdoc/require-jsdoc
2019-10-02 20:10:42 -07:00
function lintContentWrapper ( err , content ) {
if ( err ) {
return callback ( err ) ;
}
2022-06-05 22:32:22 -07:00
return lintContent ( ruleList , file , content , md , config , configParsers , frontMatter , handleRuleFailures , noInlineConfig , resultVersion , callback ) ;
2019-10-02 20:10:42 -07:00
}
// Make a/synchronous call to read file
if ( synchronous ) {
2021-08-05 22:01:29 -07:00
lintContentWrapper ( null , fs . readFileSync ( file , "utf8" ) ) ;
2019-10-02 20:10:42 -07:00
}
else {
2021-08-05 22:01:29 -07:00
fs . readFile ( file , "utf8" , lintContentWrapper ) ;
2019-10-02 20:10:42 -07:00
}
}
2020-01-27 19:19:34 -08:00
/ * *
* Lint files and strings specified in the Options object .
*
* @ param { Options } options Options object .
* @ param { boolean } synchronous Whether to execute synchronously .
* @ param { Function } callback Callback ( err , result ) function .
* @ returns { void }
* /
2019-10-02 20:10:42 -07:00
function lintInput ( options , synchronous , callback ) {
// Normalize inputs
options = options || { } ;
callback = callback || function noop ( ) { } ;
2021-02-06 19:55:22 -08:00
// eslint-disable-next-line unicorn/prefer-spread
2022-06-02 21:42:48 -07:00
const ruleList = rules . concat ( options . customRules || [ ] ) ;
const ruleErr = validateRuleList ( ruleList , synchronous ) ;
2019-10-02 20:10:42 -07:00
if ( ruleErr ) {
2022-06-11 22:40:45 -07:00
callback ( ruleErr ) ;
return ;
2019-10-02 20:10:42 -07:00
}
2022-06-02 21:42:48 -07:00
let files = [ ] ;
2019-10-02 20:10:42 -07:00
if ( Array . isArray ( options . files ) ) {
2022-06-02 21:42:48 -07:00
files = [ ... options . files ] ;
2019-10-02 20:10:42 -07:00
}
else if ( options . files ) {
files = [ String ( options . files ) ] ;
}
2022-06-02 21:42:48 -07:00
const strings = options . strings || { } ;
const stringsKeys = Object . keys ( strings ) ;
const config = options . config || { "default" : true } ;
2022-06-05 22:32:22 -07:00
const configParsers = options . configParsers || null ;
2022-06-02 21:42:48 -07:00
const frontMatter = ( options . frontMatter === undefined ) ?
2019-10-02 20:10:42 -07:00
helpers . frontMatterRe : options . frontMatter ;
2022-06-02 21:42:48 -07:00
const handleRuleFailures = ! ! options . handleRuleFailures ;
const noInlineConfig = ! ! options . noInlineConfig ;
const resultVersion = ( options . resultVersion === undefined ) ?
2022-04-21 21:30:56 -07:00
3 : options . resultVersion ;
2022-06-02 21:42:48 -07:00
const md = markdownIt ( { "html" : true } ) ;
const markdownItPlugins = options . markdownItPlugins || [ ] ;
2022-06-08 22:10:27 -07:00
for ( const plugin of markdownItPlugins ) {
2019-10-02 20:10:42 -07:00
// @ts-ignore
2022-06-02 21:42:48 -07:00
md . use ( ... plugin ) ;
2022-06-08 22:10:27 -07:00
}
2022-08-16 04:01:53 +00:00
const fs = options . fs || _ _webpack _require _ _ ( /*! node:fs */ "?d0ee" ) ;
2022-06-02 21:42:48 -07:00
const results = newResults ( ruleList ) ;
let done = false ;
let concurrency = 0 ;
2020-09-13 21:15:11 -07:00
// eslint-disable-next-line jsdoc/require-jsdoc
2021-12-03 22:43:58 -08:00
function lintWorker ( ) {
2022-06-02 21:42:48 -07:00
let currentItem = null ;
2021-12-03 22:43:58 -08:00
// eslint-disable-next-line jsdoc/require-jsdoc
function lintWorkerCallback ( err , result ) {
concurrency -- ;
if ( err ) {
done = true ;
return callback ( err ) ;
}
results [ currentItem ] = result ;
if ( ! synchronous ) {
lintWorker ( ) ;
}
return null ;
}
2020-09-13 21:15:11 -07:00
if ( done ) {
2021-12-03 22:43:58 -08:00
// Abort for error or nothing left to do
2020-09-13 21:15:11 -07:00
}
2021-12-03 22:43:58 -08:00
else if ( files . length > 0 ) {
// Lint next file
2020-09-13 21:15:11 -07:00
concurrency ++ ;
2021-12-03 22:43:58 -08:00
currentItem = files . shift ( ) ;
2022-06-05 22:32:22 -07:00
lintFile ( ruleList , currentItem , md , config , configParsers , frontMatter , handleRuleFailures , noInlineConfig , resultVersion , fs , synchronous , lintWorkerCallback ) ;
2021-12-03 22:43:58 -08:00
}
2022-06-11 22:40:45 -07:00
else if ( ( currentItem = stringsKeys . shift ( ) ) ) {
2021-12-03 22:43:58 -08:00
// Lint next string
concurrency ++ ;
2022-06-05 22:32:22 -07:00
lintContent ( ruleList , currentItem , strings [ currentItem ] || "" , md , config , configParsers , frontMatter , handleRuleFailures , noInlineConfig , resultVersion , lintWorkerCallback ) ;
2020-09-13 21:15:11 -07:00
}
else if ( concurrency === 0 ) {
2021-12-03 22:43:58 -08:00
// Finish
2020-09-13 21:15:11 -07:00
done = true ;
return callback ( null , results ) ;
}
return null ;
}
2021-12-03 22:43:58 -08:00
if ( synchronous ) {
while ( ! done ) {
lintWorker ( ) ;
}
}
else {
// Testing on a Raspberry Pi 4 Model B with an artificial 5ms file access
// delay suggests that a concurrency factor of 8 can eliminate the impact
// of that delay (i.e., total time is the same as with no delay).
lintWorker ( ) ;
lintWorker ( ) ;
lintWorker ( ) ;
lintWorker ( ) ;
lintWorker ( ) ;
lintWorker ( ) ;
lintWorker ( ) ;
lintWorker ( ) ;
}
2019-10-02 20:10:42 -07:00
}
/ * *
* Lint specified Markdown files .
*
2019-12-14 13:50:48 -08:00
* @ param { Options } options Configuration options .
* @ param { LintCallback } callback Callback ( err , result ) function .
2019-10-02 20:10:42 -07:00
* @ returns { void }
* /
function markdownlint ( options , callback ) {
return lintInput ( options , false , callback ) ;
}
2022-06-02 21:42:48 -07:00
const markdownlintPromisify = promisify && promisify ( markdownlint ) ;
2020-09-13 21:15:11 -07:00
/ * *
* Lint specified Markdown files .
*
* @ param { Options } options Configuration options .
* @ returns { Promise < LintResults > } Results object .
* /
function markdownlintPromise ( options ) {
2022-06-11 22:40:45 -07:00
// @ts-ignore
2020-09-13 21:15:11 -07:00
return markdownlintPromisify ( options ) ;
}
2019-10-02 20:10:42 -07:00
/ * *
* Lint specified Markdown files synchronously .
*
2019-12-14 13:50:48 -08:00
* @ param { Options } options Configuration options .
* @ returns { LintResults } Results object .
2019-10-02 20:10:42 -07:00
* /
function markdownlintSync ( options ) {
2022-06-11 22:40:45 -07:00
let results = { } ;
2019-10-02 20:10:42 -07:00
lintInput ( options , true , function callback ( error , res ) {
if ( error ) {
throw error ;
}
results = res ;
} ) ;
2022-06-11 22:40:45 -07:00
// @ts-ignore
2019-10-02 20:10:42 -07:00
return results ;
}
2021-08-12 20:43:18 -07:00
/ * *
* Resolve referenced "extends" path in a configuration file
* using path . resolve ( ) with require . resolve ( ) as a fallback .
*
* @ param { string } configFile Configuration file name .
* @ param { string } referenceId Referenced identifier to resolve .
* @ param { Object } fs File system implementation .
2022-06-11 22:40:45 -07:00
* @ param { ResolveConfigExtendsCallback } callback Callback ( err , result )
2021-08-12 20:43:18 -07:00
* function .
* @ returns { void }
* /
function resolveConfigExtends ( configFile , referenceId , fs , callback ) {
2022-06-02 21:42:48 -07:00
const configFileDirname = path . dirname ( configFile ) ;
const resolvedExtendsFile = path . resolve ( configFileDirname , referenceId ) ;
fs . access ( resolvedExtendsFile , ( err ) => {
2021-08-12 20:43:18 -07:00
if ( err ) {
// Not a file, try require.resolve
try {
return callback ( null , dynamicRequire . resolve ( referenceId , { "paths" : [ configFileDirname ] } ) ) ;
}
catch ( _a ) {
// Unable to resolve, use resolvedExtendsFile
}
}
return callback ( null , resolvedExtendsFile ) ;
} ) ;
}
2020-11-24 16:37:11 -08:00
/ * *
* Resolve referenced "extends" path in a configuration file
* using path . resolve ( ) with require . resolve ( ) as a fallback .
*
* @ param { string } configFile Configuration file name .
* @ param { string } referenceId Referenced identifier to resolve .
2021-08-12 19:38:03 -07:00
* @ param { Object } fs File system implementation .
2020-11-24 16:37:11 -08:00
* @ returns { string } Resolved path to file .
* /
2021-08-12 20:43:18 -07:00
function resolveConfigExtendsSync ( configFile , referenceId , fs ) {
2022-06-02 21:42:48 -07:00
const configFileDirname = path . dirname ( configFile ) ;
const resolvedExtendsFile = path . resolve ( configFileDirname , referenceId ) ;
2020-11-24 16:37:11 -08:00
try {
2021-08-12 19:38:03 -07:00
fs . accessSync ( resolvedExtendsFile ) ;
return resolvedExtendsFile ;
2020-11-24 16:37:11 -08:00
}
catch ( _a ) {
2021-08-12 19:38:03 -07:00
// Not a file, try require.resolve
2020-11-24 16:37:11 -08:00
}
try {
2021-02-11 22:16:07 -08:00
return dynamicRequire . resolve ( referenceId , { "paths" : [ configFileDirname ] } ) ;
2020-11-24 16:37:11 -08:00
}
catch ( _b ) {
2021-08-12 19:38:03 -07:00
// Unable to resolve, return resolvedExtendsFile
2020-11-24 16:37:11 -08:00
}
return resolvedExtendsFile ;
}
2019-10-02 20:10:42 -07:00
/ * *
* Read specified configuration file .
*
2019-12-14 13:50:48 -08:00
* @ param { string } file Configuration file name .
2020-01-27 19:19:34 -08:00
* @ param { ConfigurationParser [ ] | ReadConfigCallback } parsers Parsing
* function ( s ) .
2021-08-12 19:38:03 -07:00
* @ param { Object } [ fs ] File system implementation .
2020-01-27 19:19:34 -08:00
* @ param { ReadConfigCallback } [ callback ] Callback ( err , result ) function .
2019-10-02 20:10:42 -07:00
* @ returns { void }
* /
2021-08-12 19:38:03 -07:00
function readConfig ( file , parsers , fs , callback ) {
2019-10-02 20:10:42 -07:00
if ( ! callback ) {
2021-08-12 19:38:03 -07:00
if ( fs ) {
callback = fs ;
fs = null ;
}
else {
// @ts-ignore
callback = parsers ;
2022-06-11 22:40:45 -07:00
// @ts-ignore
2021-08-12 19:38:03 -07:00
parsers = null ;
}
}
if ( ! fs ) {
2022-08-16 04:01:53 +00:00
fs = _ _webpack _require _ _ ( /*! node:fs */ "?d0ee" ) ;
2019-10-02 20:10:42 -07:00
}
// Read file
2022-08-16 04:01:53 +00:00
const os = _ _webpack _require _ _ ( /*! node:os */ "?e6c4" ) ;
2022-05-16 22:57:11 -07:00
file = helpers . expandTildePath ( file , os ) ;
2022-06-02 21:42:48 -07:00
fs . readFile ( file , "utf8" , ( err , content ) => {
2019-10-02 20:10:42 -07:00
if ( err ) {
2022-06-11 22:40:45 -07:00
// @ts-ignore
2019-10-02 20:10:42 -07:00
return callback ( err ) ;
}
// Try to parse file
2020-01-27 19:19:34 -08:00
// @ts-ignore
2022-06-02 21:42:48 -07:00
const { config , message } = parseConfiguration ( file , content , parsers ) ;
2019-10-02 20:10:42 -07:00
if ( ! config ) {
2022-06-11 22:40:45 -07:00
// @ts-ignore
2019-10-02 20:10:42 -07:00
return callback ( new Error ( message ) ) ;
}
// Extend configuration
2022-06-02 21:42:48 -07:00
const configExtends = config . extends ;
2019-10-02 20:10:42 -07:00
if ( configExtends ) {
2021-11-13 12:40:51 -08:00
delete config . extends ;
2022-06-11 22:40:45 -07:00
return resolveConfigExtends ( file , helpers . expandTildePath ( configExtends , os ) , fs , ( _ , resolvedExtends ) => readConfig (
// @ts-ignore
resolvedExtends , parsers , fs , ( errr , extendsConfig ) => {
2019-10-02 20:10:42 -07:00
if ( errr ) {
2022-06-11 22:40:45 -07:00
// @ts-ignore
2019-10-02 20:10:42 -07:00
return callback ( errr ) ;
}
2022-06-11 22:40:45 -07:00
// @ts-ignore
2022-06-02 21:42:48 -07:00
return callback ( null , Object . assign ( Object . assign ( { } , extendsConfig ) , config ) ) ;
} ) ) ;
2019-10-02 20:10:42 -07:00
}
2022-06-11 22:40:45 -07:00
// @ts-ignore
2019-10-02 20:10:42 -07:00
return callback ( null , config ) ;
} ) ;
}
2022-06-02 21:42:48 -07:00
const readConfigPromisify = promisify && promisify ( readConfig ) ;
2020-09-13 21:15:11 -07:00
/ * *
* Read specified configuration file .
*
* @ param { string } file Configuration file name .
* @ param { ConfigurationParser [ ] } [ parsers ] Parsing function ( s ) .
2021-08-12 19:38:03 -07:00
* @ param { Object } [ fs ] File system implementation .
2020-09-13 21:15:11 -07:00
* @ returns { Promise < Configuration > } Configuration object .
* /
2021-08-12 19:38:03 -07:00
function readConfigPromise ( file , parsers , fs ) {
2020-09-13 21:15:11 -07:00
// @ts-ignore
2021-08-12 19:38:03 -07:00
return readConfigPromisify ( file , parsers , fs ) ;
2020-09-13 21:15:11 -07:00
}
2019-10-02 20:10:42 -07:00
/ * *
* Read specified configuration file synchronously .
*
2019-12-14 13:50:48 -08:00
* @ param { string } file Configuration file name .
* @ param { ConfigurationParser [ ] } [ parsers ] Parsing function ( s ) .
2021-08-12 19:38:03 -07:00
* @ param { Object } [ fs ] File system implementation .
2019-12-14 13:50:48 -08:00
* @ returns { Configuration } Configuration object .
2021-08-22 18:03:26 -07:00
* @ throws An Error if processing fails .
2019-10-02 20:10:42 -07:00
* /
2021-08-12 19:38:03 -07:00
function readConfigSync ( file , parsers , fs ) {
if ( ! fs ) {
2022-08-16 04:01:53 +00:00
fs = _ _webpack _require _ _ ( /*! node:fs */ "?d0ee" ) ;
2021-08-12 19:38:03 -07:00
}
2019-10-02 20:10:42 -07:00
// Read file
2022-08-16 04:01:53 +00:00
const os = _ _webpack _require _ _ ( /*! node:os */ "?e6c4" ) ;
2022-05-16 22:57:11 -07:00
file = helpers . expandTildePath ( file , os ) ;
2022-06-02 21:42:48 -07:00
const content = fs . readFileSync ( file , "utf8" ) ;
2019-10-02 20:10:42 -07:00
// Try to parse file
2022-06-02 21:42:48 -07:00
const { config , message } = parseConfiguration ( file , content , parsers ) ;
2019-10-02 20:10:42 -07:00
if ( ! config ) {
throw new Error ( message ) ;
}
// Extend configuration
2022-06-02 21:42:48 -07:00
const configExtends = config . extends ;
2019-10-02 20:10:42 -07:00
if ( configExtends ) {
2021-11-13 12:40:51 -08:00
delete config . extends ;
2022-06-02 21:42:48 -07:00
const resolvedExtends = resolveConfigExtendsSync ( file , helpers . expandTildePath ( configExtends , os ) , fs ) ;
return Object . assign ( Object . assign ( { } , readConfigSync ( resolvedExtends , parsers , fs ) ) , config ) ;
2019-10-02 20:10:42 -07:00
}
return config ;
}
2020-10-20 20:16:49 -07:00
/ * *
* Gets the ( semantic ) version of the library .
*
* @ returns { string } SemVer string .
* /
function getVersion ( ) {
2021-12-19 03:55:10 +00:00
return ( _ _webpack _require _ _ ( /*! ./constants */ "../lib/constants.js" ) . version ) ;
2020-10-20 20:16:49 -07:00
}
2020-09-13 21:15:11 -07:00
// Export a/synchronous/Promise APIs
2019-10-02 20:10:42 -07:00
markdownlint . sync = markdownlintSync ;
markdownlint . readConfig = readConfig ;
markdownlint . readConfigSync = readConfigSync ;
2020-10-20 20:16:49 -07:00
markdownlint . getVersion = getVersion ;
2020-09-13 21:15:11 -07:00
markdownlint . promises = {
"markdownlint" : markdownlintPromise ,
"readConfig" : readConfigPromise
} ;
2019-10-02 20:10:42 -07:00
module . exports = markdownlint ;
2021-01-05 20:55:09 -08:00
/***/ } ) ,
2021-01-06 19:45:15 -08:00
/***/ "../lib/md001.js" :
/ * ! * * * * * * * * * * * * * * * * * * * * * * * ! * \
! * * * . . / lib / md001 . js * * * !
\ * * * * * * * * * * * * * * * * * * * * * * * /
2021-01-05 20:55:09 -08:00
/***/ ( ( module , _ _unused _webpack _exports , _ _webpack _require _ _ ) => {
2019-10-02 20:10:42 -07:00
"use strict" ;
2021-01-05 20:55:09 -08:00
// @ts-check
2022-06-02 21:42:48 -07:00
const { addErrorDetailIf , filterTokens } = _ _webpack _require _ _ ( /*! ../helpers */ "../helpers/helpers.js" ) ;
2019-10-02 20:10:42 -07:00
module . exports = {
"names" : [ "MD001" , "heading-increment" , "header-increment" ] ,
"description" : "Heading levels should only increment by one level at a time" ,
"tags" : [ "headings" , "headers" ] ,
"function" : function MD001 ( params , onError ) {
2022-06-02 21:42:48 -07:00
let prevLevel = 0 ;
2019-10-02 20:10:42 -07:00
filterTokens ( params , "heading_open" , function forToken ( token ) {
2022-06-02 21:42:48 -07:00
const level = Number . parseInt ( token . tag . slice ( 1 ) , 10 ) ;
2019-10-02 20:10:42 -07:00
if ( prevLevel && ( level > prevLevel ) ) {
addErrorDetailIf ( onError , token . lineNumber , "h" + ( prevLevel + 1 ) , "h" + level ) ;
}
prevLevel = level ;
} ) ;
}
} ;
2021-01-05 20:55:09 -08:00
/***/ } ) ,
2021-01-06 19:45:15 -08:00
/***/ "../lib/md002.js" :
/ * ! * * * * * * * * * * * * * * * * * * * * * * * ! * \
! * * * . . / lib / md002 . js * * * !
\ * * * * * * * * * * * * * * * * * * * * * * * /
2021-01-05 20:55:09 -08:00
/***/ ( ( module , _ _unused _webpack _exports , _ _webpack _require _ _ ) => {
2019-10-02 20:10:42 -07:00
"use strict" ;
2021-01-05 20:55:09 -08:00
// @ts-check
2022-06-02 21:42:48 -07:00
const { addErrorDetailIf } = _ _webpack _require _ _ ( /*! ../helpers */ "../helpers/helpers.js" ) ;
2019-10-02 20:10:42 -07:00
module . exports = {
"names" : [ "MD002" , "first-heading-h1" , "first-header-h1" ] ,
2020-12-28 13:28:38 -08:00
"description" : "First heading should be a top-level heading" ,
2019-10-02 20:10:42 -07:00
"tags" : [ "headings" , "headers" ] ,
"function" : function MD002 ( params , onError ) {
2022-06-02 21:42:48 -07:00
const level = Number ( params . config . level || 1 ) ;
const tag = "h" + level ;
2019-10-02 20:10:42 -07:00
params . tokens . every ( function forToken ( token ) {
if ( token . type === "heading_open" ) {
addErrorDetailIf ( onError , token . lineNumber , tag , token . tag ) ;
return false ;
}
return true ;
} ) ;
}
} ;
2021-01-05 20:55:09 -08:00
/***/ } ) ,
2021-01-06 19:45:15 -08:00
/***/ "../lib/md003.js" :
/ * ! * * * * * * * * * * * * * * * * * * * * * * * ! * \
! * * * . . / lib / md003 . js * * * !
\ * * * * * * * * * * * * * * * * * * * * * * * /
2021-01-05 20:55:09 -08:00
/***/ ( ( module , _ _unused _webpack _exports , _ _webpack _require _ _ ) => {
2019-10-02 20:10:42 -07:00
"use strict" ;
2021-01-05 20:55:09 -08:00
// @ts-check
2022-06-02 21:42:48 -07:00
const { addErrorDetailIf , filterTokens , headingStyleFor } = _ _webpack _require _ _ ( /*! ../helpers */ "../helpers/helpers.js" ) ;
2019-10-02 20:10:42 -07:00
module . exports = {
"names" : [ "MD003" , "heading-style" , "header-style" ] ,
"description" : "Heading style" ,
"tags" : [ "headings" , "headers" ] ,
"function" : function MD003 ( params , onError ) {
2022-06-02 21:42:48 -07:00
let style = String ( params . config . style || "consistent" ) ;
2019-10-02 20:10:42 -07:00
filterTokens ( params , "heading_open" , function forToken ( token ) {
2022-06-02 21:42:48 -07:00
const styleForToken = headingStyleFor ( token ) ;
2019-10-02 20:10:42 -07:00
if ( style === "consistent" ) {
style = styleForToken ;
}
if ( styleForToken !== style ) {
2022-06-02 21:42:48 -07:00
const h12 = /h[12]/ . test ( token . tag ) ;
const setextWithAtx = ( style === "setext_with_atx" ) &&
2019-10-02 20:10:42 -07:00
( ( h12 && ( styleForToken === "setext" ) ) ||
( ! h12 && ( styleForToken === "atx" ) ) ) ;
2022-06-02 21:42:48 -07:00
const setextWithAtxClosed = ( style === "setext_with_atx_closed" ) &&
2019-10-02 20:10:42 -07:00
( ( h12 && ( styleForToken === "setext" ) ) ||
( ! h12 && ( styleForToken === "atx_closed" ) ) ) ;
if ( ! setextWithAtx && ! setextWithAtxClosed ) {
2022-06-02 21:42:48 -07:00
let expected = style ;
2019-10-02 20:10:42 -07:00
if ( style === "setext_with_atx" ) {
expected = h12 ? "setext" : "atx" ;
}
else if ( style === "setext_with_atx_closed" ) {
expected = h12 ? "setext" : "atx_closed" ;
}
addErrorDetailIf ( onError , token . lineNumber , expected , styleForToken ) ;
}
}
} ) ;
}
} ;
2021-01-05 20:55:09 -08:00
/***/ } ) ,
2021-01-06 19:45:15 -08:00
/***/ "../lib/md004.js" :
/ * ! * * * * * * * * * * * * * * * * * * * * * * * ! * \
! * * * . . / lib / md004 . js * * * !
\ * * * * * * * * * * * * * * * * * * * * * * * /
2021-01-05 20:55:09 -08:00
/***/ ( ( module , _ _unused _webpack _exports , _ _webpack _require _ _ ) => {
2019-10-02 20:10:42 -07:00
"use strict" ;
2021-01-05 20:55:09 -08:00
// @ts-check
2022-06-02 21:42:48 -07:00
const { addErrorDetailIf , listItemMarkerRe , unorderedListStyleFor } = _ _webpack _require _ _ ( /*! ../helpers */ "../helpers/helpers.js" ) ;
const { flattenedLists } = _ _webpack _require _ _ ( /*! ./cache */ "../lib/cache.js" ) ;
const expectedStyleToMarker = {
2021-02-06 15:49:02 -08:00
"dash" : "-" ,
"plus" : "+" ,
"asterisk" : "*"
} ;
2022-06-02 21:42:48 -07:00
const differentItemStyle = {
2021-02-06 15:49:02 -08:00
"dash" : "plus" ,
"plus" : "asterisk" ,
"asterisk" : "dash"
} ;
2022-06-02 21:42:48 -07:00
const validStyles = Object . keys ( expectedStyleToMarker ) ;
2019-10-02 20:10:42 -07:00
module . exports = {
"names" : [ "MD004" , "ul-style" ] ,
"description" : "Unordered list style" ,
"tags" : [ "bullet" , "ul" ] ,
"function" : function MD004 ( params , onError ) {
2022-06-02 21:42:48 -07:00
const style = String ( params . config . style || "consistent" ) ;
let expectedStyle = style ;
const nestingStyles = [ ] ;
2022-06-08 22:10:27 -07:00
for ( const list of flattenedLists ( ) ) {
2019-10-02 20:10:42 -07:00
if ( list . unordered ) {
if ( expectedStyle === "consistent" ) {
expectedStyle = unorderedListStyleFor ( list . items [ 0 ] ) ;
}
2022-06-08 22:10:27 -07:00
for ( const item of list . items ) {
2022-06-02 21:42:48 -07:00
const itemStyle = unorderedListStyleFor ( item ) ;
2019-10-02 20:10:42 -07:00
if ( style === "sublist" ) {
2022-06-02 21:42:48 -07:00
const nesting = list . nesting ;
2021-02-06 15:49:02 -08:00
if ( ! nestingStyles [ nesting ] ) {
nestingStyles [ nesting ] =
( itemStyle === nestingStyles [ nesting - 1 ] ) ?
differentItemStyle [ itemStyle ] :
itemStyle ;
2019-10-02 20:10:42 -07:00
}
2021-02-06 15:49:02 -08:00
expectedStyle = nestingStyles [ nesting ] ;
2019-10-02 20:10:42 -07:00
}
2021-02-06 16:09:16 -08:00
if ( ! validStyles . includes ( expectedStyle ) ) {
expectedStyle = validStyles [ 0 ] ;
}
2022-06-02 21:42:48 -07:00
let range = null ;
let fixInfo = null ;
const match = item . line . match ( listItemMarkerRe ) ;
2021-02-06 15:49:02 -08:00
if ( match ) {
2022-06-02 21:42:48 -07:00
const column = match . index + 1 ;
const length = match [ 0 ] . length ;
2021-11-13 12:40:51 -08:00
range = [ column , length ] ;
2021-02-06 15:49:02 -08:00
fixInfo = {
"editColumn" : match [ 1 ] . length + 1 ,
"deleteCount" : 1 ,
"insertText" : expectedStyleToMarker [ expectedStyle ]
} ;
2019-10-02 20:10:42 -07:00
}
2021-02-06 15:49:02 -08:00
addErrorDetailIf ( onError , item . lineNumber , expectedStyle , itemStyle , null , null , range , fixInfo ) ;
2022-06-08 22:10:27 -07:00
}
2019-10-02 20:10:42 -07:00
}
2022-06-08 22:10:27 -07:00
}
2019-10-02 20:10:42 -07:00
}
} ;
2021-01-05 20:55:09 -08:00
/***/ } ) ,
2021-01-06 19:45:15 -08:00
/***/ "../lib/md005.js" :
/ * ! * * * * * * * * * * * * * * * * * * * * * * * ! * \
! * * * . . / lib / md005 . js * * * !
\ * * * * * * * * * * * * * * * * * * * * * * * /
2021-01-05 20:55:09 -08:00
/***/ ( ( module , _ _unused _webpack _exports , _ _webpack _require _ _ ) => {
2019-10-02 20:10:42 -07:00
"use strict" ;
2021-01-05 20:55:09 -08:00
// @ts-check
2022-06-02 21:42:48 -07:00
const { addError , addErrorDetailIf , indentFor , listItemMarkerRe , orderedListItemMarkerRe , rangeFromRegExp } = _ _webpack _require _ _ ( /*! ../helpers */ "../helpers/helpers.js" ) ;
const { flattenedLists } = _ _webpack _require _ _ ( /*! ./cache */ "../lib/cache.js" ) ;
2019-10-02 20:10:42 -07:00
module . exports = {
"names" : [ "MD005" , "list-indent" ] ,
"description" : "Inconsistent indentation for list items at the same level" ,
"tags" : [ "bullet" , "ul" , "indentation" ] ,
"function" : function MD005 ( params , onError ) {
2022-06-08 22:10:27 -07:00
for ( const list of flattenedLists ( ) ) {
2022-06-02 21:42:48 -07:00
const expectedIndent = list . indent ;
let expectedEnd = 0 ;
let actualEnd = - 1 ;
let endMatching = false ;
2022-06-08 22:10:27 -07:00
for ( const item of list . items ) {
2022-06-02 21:42:48 -07:00
const { line , lineNumber } = item ;
const actualIndent = indentFor ( item ) ;
let match = null ;
2019-10-02 20:10:42 -07:00
if ( list . unordered ) {
2020-01-27 19:19:34 -08:00
addErrorDetailIf ( onError , lineNumber , expectedIndent , actualIndent , null , null , rangeFromRegExp ( line , listItemMarkerRe )
// No fixInfo; MD007 handles this scenario better
) ;
2019-10-02 20:10:42 -07:00
}
2020-04-11 13:54:46 -07:00
else if ( ( match = orderedListItemMarkerRe . exec ( line ) ) ) {
2020-01-27 19:19:34 -08:00
actualEnd = match [ 0 ] . length ;
2019-10-02 20:10:42 -07:00
expectedEnd = expectedEnd || actualEnd ;
2022-06-02 21:42:48 -07:00
const markerLength = match [ 1 ] . length + 1 ;
2019-10-02 20:10:42 -07:00
if ( ( expectedIndent !== actualIndent ) || endMatching ) {
if ( expectedEnd === actualEnd ) {
endMatching = true ;
}
else {
2022-06-02 21:42:48 -07:00
const detail = endMatching ?
` Expected: ( ${ expectedEnd } ); Actual: ( ${ actualEnd } ) ` :
` Expected: ${ expectedIndent } ; Actual: ${ actualIndent } ` ;
const expected = endMatching ?
2020-01-27 19:19:34 -08:00
expectedEnd - markerLength :
expectedIndent ;
2022-06-02 21:42:48 -07:00
const actual = endMatching ?
2020-01-27 19:19:34 -08:00
actualEnd - markerLength :
actualIndent ;
addError ( onError , lineNumber , detail , null , rangeFromRegExp ( line , listItemMarkerRe ) , {
"editColumn" : Math . min ( actual , expected ) + 1 ,
"deleteCount" : Math . max ( actual - expected , 0 ) ,
"insertText" : "" . padEnd ( Math . max ( expected - actual , 0 ) )
} ) ;
2019-10-02 20:10:42 -07:00
}
}
}
2022-06-08 22:10:27 -07:00
}
}
2019-10-02 20:10:42 -07:00
}
} ;
2021-01-05 20:55:09 -08:00
/***/ } ) ,
2021-01-06 19:45:15 -08:00
/***/ "../lib/md006.js" :
/ * ! * * * * * * * * * * * * * * * * * * * * * * * ! * \
! * * * . . / lib / md006 . js * * * !
\ * * * * * * * * * * * * * * * * * * * * * * * /
2021-01-05 20:55:09 -08:00
/***/ ( ( module , _ _unused _webpack _exports , _ _webpack _require _ _ ) => {
2019-10-02 20:10:42 -07:00
"use strict" ;
2021-01-05 20:55:09 -08:00
// @ts-check
2022-06-02 21:42:48 -07:00
const { addErrorDetailIf , listItemMarkerRe , rangeFromRegExp } = _ _webpack _require _ _ ( /*! ../helpers */ "../helpers/helpers.js" ) ;
const { flattenedLists } = _ _webpack _require _ _ ( /*! ./cache */ "../lib/cache.js" ) ;
2019-10-02 20:10:42 -07:00
module . exports = {
"names" : [ "MD006" , "ul-start-left" ] ,
"description" : "Consider starting bulleted lists at the beginning of the line" ,
"tags" : [ "bullet" , "ul" , "indentation" ] ,
"function" : function MD006 ( params , onError ) {
2022-06-08 22:10:27 -07:00
for ( const list of flattenedLists ( ) ) {
2019-10-02 20:10:42 -07:00
if ( list . unordered && ! list . nesting && ( list . indent !== 0 ) ) {
2022-06-08 22:10:27 -07:00
for ( const item of list . items ) {
2022-06-02 21:42:48 -07:00
const { lineNumber , line } = item ;
2019-12-14 13:50:48 -08:00
addErrorDetailIf ( onError , lineNumber , 0 , list . indent , null , null , rangeFromRegExp ( line , listItemMarkerRe ) , {
2021-02-06 19:55:22 -08:00
"deleteCount" : line . length - line . trimStart ( ) . length
2019-12-14 13:50:48 -08:00
} ) ;
2022-06-08 22:10:27 -07:00
}
2019-10-02 20:10:42 -07:00
}
2022-06-08 22:10:27 -07:00
}
2019-10-02 20:10:42 -07:00
}
} ;
2021-01-05 20:55:09 -08:00
/***/ } ) ,
2021-01-06 19:45:15 -08:00
/***/ "../lib/md007.js" :
/ * ! * * * * * * * * * * * * * * * * * * * * * * * ! * \
! * * * . . / lib / md007 . js * * * !
\ * * * * * * * * * * * * * * * * * * * * * * * /
2021-01-05 20:55:09 -08:00
/***/ ( ( module , _ _unused _webpack _exports , _ _webpack _require _ _ ) => {
2019-10-02 20:10:42 -07:00
"use strict" ;
2021-01-05 20:55:09 -08:00
// @ts-check
2022-06-02 21:42:48 -07:00
const { addErrorDetailIf , indentFor , listItemMarkerRe } = _ _webpack _require _ _ ( /*! ../helpers */ "../helpers/helpers.js" ) ;
const { flattenedLists } = _ _webpack _require _ _ ( /*! ./cache */ "../lib/cache.js" ) ;
2019-10-02 20:10:42 -07:00
module . exports = {
"names" : [ "MD007" , "ul-indent" ] ,
"description" : "Unordered list indentation" ,
"tags" : [ "bullet" , "ul" , "indentation" ] ,
"function" : function MD007 ( params , onError ) {
2022-06-02 21:42:48 -07:00
const indent = Number ( params . config . indent || 2 ) ;
const startIndented = ! ! params . config . start _indented ;
const startIndent = Number ( params . config . start _indent || indent ) ;
2022-06-08 22:10:27 -07:00
for ( const list of flattenedLists ( ) ) {
2019-12-14 13:50:48 -08:00
if ( list . unordered && list . parentsUnordered ) {
2022-06-08 22:10:27 -07:00
for ( const item of list . items ) {
2022-06-02 21:42:48 -07:00
const { lineNumber , line } = item ;
const expectedIndent = ( startIndented ? startIndent : 0 ) +
2021-12-13 21:49:43 -08:00
( list . nesting * indent ) ;
2022-06-02 21:42:48 -07:00
const actualIndent = indentFor ( item ) ;
let range = null ;
let editColumn = 1 ;
const match = line . match ( listItemMarkerRe ) ;
2019-12-14 13:50:48 -08:00
if ( match ) {
range = [ 1 , match [ 0 ] . length ] ;
editColumn += match [ 1 ] . length - actualIndent ;
}
addErrorDetailIf ( onError , lineNumber , expectedIndent , actualIndent , null , null , range , {
2022-06-02 21:42:48 -07:00
editColumn ,
2019-12-14 13:50:48 -08:00
"deleteCount" : actualIndent ,
"insertText" : "" . padEnd ( expectedIndent )
} ) ;
2022-06-08 22:10:27 -07:00
}
2019-10-02 20:10:42 -07:00
}
2022-06-08 22:10:27 -07:00
}
2019-10-02 20:10:42 -07:00
}
} ;
2021-01-05 20:55:09 -08:00
/***/ } ) ,
2021-01-06 19:45:15 -08:00
/***/ "../lib/md009.js" :
/ * ! * * * * * * * * * * * * * * * * * * * * * * * ! * \
! * * * . . / lib / md009 . js * * * !
\ * * * * * * * * * * * * * * * * * * * * * * * /
2021-01-05 20:55:09 -08:00
/***/ ( ( module , _ _unused _webpack _exports , _ _webpack _require _ _ ) => {
2019-10-02 20:10:42 -07:00
"use strict" ;
2021-01-05 20:55:09 -08:00
// @ts-check
2022-06-16 05:19:27 +00:00
const { addError , filterTokens , forEachLine , includesSorted , numericSortAscending } = _ _webpack _require _ _ ( /*! ../helpers */ "../helpers/helpers.js" ) ;
2022-06-02 21:42:48 -07:00
const { lineMetadata } = _ _webpack _require _ _ ( /*! ./cache */ "../lib/cache.js" ) ;
2019-10-02 20:10:42 -07:00
module . exports = {
"names" : [ "MD009" , "no-trailing-spaces" ] ,
"description" : "Trailing spaces" ,
"tags" : [ "whitespace" ] ,
"function" : function MD009 ( params , onError ) {
2022-06-02 21:42:48 -07:00
let brSpaces = params . config . br _spaces ;
2020-01-27 19:19:34 -08:00
brSpaces = Number ( ( brSpaces === undefined ) ? 2 : brSpaces ) ;
2022-06-02 21:42:48 -07:00
const listItemEmptyLines = ! ! params . config . list _item _empty _lines ;
const strict = ! ! params . config . strict ;
const listItemLineNumbers = [ ] ;
2019-12-14 13:50:48 -08:00
if ( listItemEmptyLines ) {
2022-06-02 21:42:48 -07:00
filterTokens ( params , "list_item_open" , ( token ) => {
for ( let i = token . map [ 0 ] ; i < token . map [ 1 ] ; i ++ ) {
2019-10-02 20:10:42 -07:00
listItemLineNumbers . push ( i + 1 ) ;
}
} ) ;
2019-12-14 13:50:48 -08:00
listItemLineNumbers . sort ( numericSortAscending ) ;
}
2022-06-02 21:42:48 -07:00
const paragraphLineNumbers = [ ] ;
const codeInlineLineNumbers = [ ] ;
2019-12-14 13:50:48 -08:00
if ( strict ) {
2022-06-02 21:42:48 -07:00
filterTokens ( params , "paragraph_open" , ( token ) => {
for ( let i = token . map [ 0 ] ; i < token . map [ 1 ] - 1 ; i ++ ) {
2019-12-14 13:50:48 -08:00
paragraphLineNumbers . push ( i + 1 ) ;
}
} ) ;
2022-06-16 05:19:27 +00:00
const addLineNumberRange = ( start , end ) => {
for ( let i = start ; i < end ; i ++ ) {
codeInlineLineNumbers . push ( i ) ;
}
} ;
2022-06-02 21:42:48 -07:00
filterTokens ( params , "inline" , ( token ) => {
2022-06-16 05:19:27 +00:00
let start = 0 ;
for ( const child of token . children ) {
if ( start > 0 ) {
addLineNumberRange ( start , child . lineNumber ) ;
start = 0 ;
}
if ( child . type === "code_inline" ) {
start = child . lineNumber ;
}
}
if ( start > 0 ) {
addLineNumberRange ( start , token . map [ 1 ] ) ;
2019-12-14 13:50:48 -08:00
}
} ) ;
2019-10-02 20:10:42 -07:00
}
2022-06-02 21:42:48 -07:00
const expected = ( brSpaces < 2 ) ? 0 : brSpaces ;
forEachLine ( lineMetadata ( ) , ( line , lineIndex , inCode ) => {
const lineNumber = lineIndex + 1 ;
const trailingSpaces = line . length - line . trimEnd ( ) . length ;
2021-02-06 19:55:22 -08:00
if ( trailingSpaces &&
! inCode &&
! includesSorted ( listItemLineNumbers , lineNumber ) &&
( ( expected !== trailingSpaces ) ||
2019-12-14 13:50:48 -08:00
( strict &&
( ! includesSorted ( paragraphLineNumbers , lineNumber ) ||
2021-02-06 19:55:22 -08:00
includesSorted ( codeInlineLineNumbers , lineNumber ) ) ) ) ) {
2022-06-02 21:42:48 -07:00
const column = line . length - trailingSpaces + 1 ;
2021-02-06 19:55:22 -08:00
addError ( onError , lineNumber , "Expected: " + ( expected === 0 ? "" : "0 or " ) +
2022-06-13 22:53:48 -07:00
expected + "; Actual: " + trailingSpaces , undefined , [ column , trailingSpaces ] , {
2021-02-06 19:55:22 -08:00
"editColumn" : column ,
"deleteCount" : trailingSpaces
} ) ;
2019-10-02 20:10:42 -07:00
}
} ) ;
}
} ;
2021-01-05 20:55:09 -08:00
/***/ } ) ,
2021-01-06 19:45:15 -08:00
/***/ "../lib/md010.js" :
/ * ! * * * * * * * * * * * * * * * * * * * * * * * ! * \
! * * * . . / lib / md010 . js * * * !
\ * * * * * * * * * * * * * * * * * * * * * * * /
2021-01-05 20:55:09 -08:00
/***/ ( ( module , _ _unused _webpack _exports , _ _webpack _require _ _ ) => {
2019-10-02 20:10:42 -07:00
"use strict" ;
2021-01-05 20:55:09 -08:00
// @ts-check
2022-06-02 22:17:32 -07:00
const { addError , filterTokens , forEachLine , withinAnyRange } = _ _webpack _require _ _ ( /*! ../helpers */ "../helpers/helpers.js" ) ;
2022-06-02 21:42:48 -07:00
const { codeBlockAndSpanRanges , lineMetadata } = _ _webpack _require _ _ ( /*! ./cache */ "../lib/cache.js" ) ;
const tabRe = /\t+/g ;
2019-10-02 20:10:42 -07:00
module . exports = {
"names" : [ "MD010" , "no-hard-tabs" ] ,
"description" : "Hard tabs" ,
"tags" : [ "whitespace" , "hard_tab" ] ,
"function" : function MD010 ( params , onError ) {
2022-06-02 21:42:48 -07:00
const codeBlocks = params . config . code _blocks ;
const includeCode = ( codeBlocks === undefined ) ? true : ! ! codeBlocks ;
const ignoreCodeLanguages = new Set ( ( params . config . ignore _code _languages || [ ] )
. map ( ( language ) => language . toLowerCase ( ) ) ) ;
const spacesPerTab = params . config . spaces _per _tab ;
const spaceMultiplier = ( spacesPerTab === undefined ) ?
2021-04-09 16:33:01 -07:00
1 :
Math . max ( 0 , Number ( spacesPerTab ) ) ;
2022-06-02 21:42:48 -07:00
const exclusions = includeCode ? [ ] : codeBlockAndSpanRanges ( ) ;
filterTokens ( params , "fence" , ( token ) => {
const language = token . info . trim ( ) . toLowerCase ( ) ;
2022-04-28 21:09:06 -07:00
if ( ignoreCodeLanguages . has ( language ) ) {
2022-06-02 21:42:48 -07:00
for ( let i = token . map [ 0 ] + 1 ; i < token . map [ 1 ] - 1 ; i ++ ) {
2022-04-28 21:09:06 -07:00
exclusions . push ( [ i , 0 , params . lines [ i ] . length ] ) ;
}
}
} ) ;
2022-06-02 21:42:48 -07:00
forEachLine ( lineMetadata ( ) , ( line , lineIndex , inCode ) => {
2021-12-17 17:24:00 -08:00
if ( includeCode || ! inCode ) {
2022-06-02 21:42:48 -07:00
let match = null ;
2019-10-02 20:10:42 -07:00
while ( ( match = tabRe . exec ( line ) ) !== null ) {
2022-06-02 21:42:48 -07:00
const { index } = match ;
const column = index + 1 ;
const length = match [ 0 ] . length ;
2022-06-02 22:17:32 -07:00
if ( ! withinAnyRange ( exclusions , lineIndex , index , length ) ) {
2021-12-17 17:24:00 -08:00
addError ( onError , lineIndex + 1 , "Column: " + column , null , [ column , length ] , {
"editColumn" : column ,
"deleteCount" : length ,
"insertText" : "" . padEnd ( length * spaceMultiplier )
} ) ;
}
2019-10-02 20:10:42 -07:00
}
}
} ) ;
}
} ;
2021-01-05 20:55:09 -08:00
/***/ } ) ,
2021-01-06 19:45:15 -08:00
/***/ "../lib/md011.js" :
/ * ! * * * * * * * * * * * * * * * * * * * * * * * ! * \
! * * * . . / lib / md011 . js * * * !
\ * * * * * * * * * * * * * * * * * * * * * * * /
2021-01-05 20:55:09 -08:00
/***/ ( ( module , _ _unused _webpack _exports , _ _webpack _require _ _ ) => {
2019-10-02 20:10:42 -07:00
"use strict" ;
2021-01-05 20:55:09 -08:00
// @ts-check
2022-06-02 22:17:32 -07:00
const { addError , forEachLine , withinAnyRange } = _ _webpack _require _ _ ( /*! ../helpers */ "../helpers/helpers.js" ) ;
2022-06-02 21:42:48 -07:00
const { codeBlockAndSpanRanges , lineMetadata } = _ _webpack _require _ _ ( /*! ./cache */ "../lib/cache.js" ) ;
2022-10-16 22:16:51 -07:00
const reversedLinkRe = /(^|[^\\])\(([^()]+)\)\[([^\]^][^\]]*)](?!\()/g ;
2019-10-02 20:10:42 -07:00
module . exports = {
"names" : [ "MD011" , "no-reversed-links" ] ,
"description" : "Reversed link syntax" ,
"tags" : [ "links" ] ,
"function" : function MD011 ( params , onError ) {
2022-06-02 21:42:48 -07:00
const exclusions = codeBlockAndSpanRanges ( ) ;
forEachLine ( lineMetadata ( ) , ( line , lineIndex , inCode , onFence ) => {
2021-06-17 21:50:03 -07:00
if ( ! inCode && ! onFence ) {
2022-06-02 21:42:48 -07:00
let match = null ;
2021-06-17 21:50:03 -07:00
while ( ( match = reversedLinkRe . exec ( line ) ) !== null ) {
2022-06-02 21:42:48 -07:00
const [ reversedLink , preChar , linkText , linkDestination ] = match ;
const index = match . index + preChar . length ;
const length = match [ 0 ] . length - preChar . length ;
2021-08-22 22:26:12 -07:00
if ( ! linkText . endsWith ( "\\" ) &&
! linkDestination . endsWith ( "\\" ) &&
2022-06-02 22:17:32 -07:00
! withinAnyRange ( exclusions , lineIndex , index , length ) ) {
2022-10-16 22:16:51 -07:00
addError ( onError , lineIndex + 1 , reversedLink . slice ( preChar . length ) , undefined , [ index + 1 , length ] , {
2021-06-17 21:50:03 -07:00
"editColumn" : index + 1 ,
2021-11-13 12:40:51 -08:00
"deleteCount" : length ,
2022-06-02 21:42:48 -07:00
"insertText" : ` [ ${ linkText } ]( ${ linkDestination } ) `
2021-06-17 21:50:03 -07:00
} ) ;
}
}
2019-10-02 20:10:42 -07:00
}
} ) ;
}
} ;
2021-01-05 20:55:09 -08:00
/***/ } ) ,
2021-01-06 19:45:15 -08:00
/***/ "../lib/md012.js" :
/ * ! * * * * * * * * * * * * * * * * * * * * * * * ! * \
! * * * . . / lib / md012 . js * * * !
\ * * * * * * * * * * * * * * * * * * * * * * * /
2021-01-05 20:55:09 -08:00
/***/ ( ( module , _ _unused _webpack _exports , _ _webpack _require _ _ ) => {
2019-10-02 20:10:42 -07:00
"use strict" ;
2021-01-05 20:55:09 -08:00
// @ts-check
2022-06-02 21:42:48 -07:00
const { addErrorDetailIf , forEachLine } = _ _webpack _require _ _ ( /*! ../helpers */ "../helpers/helpers.js" ) ;
const { lineMetadata } = _ _webpack _require _ _ ( /*! ./cache */ "../lib/cache.js" ) ;
2019-10-02 20:10:42 -07:00
module . exports = {
"names" : [ "MD012" , "no-multiple-blanks" ] ,
"description" : "Multiple consecutive blank lines" ,
"tags" : [ "whitespace" , "blank_lines" ] ,
"function" : function MD012 ( params , onError ) {
2022-06-02 21:42:48 -07:00
const maximum = Number ( params . config . maximum || 1 ) ;
let count = 0 ;
forEachLine ( lineMetadata ( ) , ( line , lineIndex , inCode ) => {
2020-09-13 21:15:11 -07:00
count = ( inCode || ( line . trim ( ) . length > 0 ) ) ? 0 : count + 1 ;
2019-10-02 20:10:42 -07:00
if ( maximum < count ) {
addErrorDetailIf ( onError , lineIndex + 1 , maximum , count , null , null , null , {
"deleteCount" : - 1
} ) ;
}
} ) ;
}
} ;
2021-01-05 20:55:09 -08:00
/***/ } ) ,
2021-01-06 19:45:15 -08:00
/***/ "../lib/md013.js" :
/ * ! * * * * * * * * * * * * * * * * * * * * * * * ! * \
! * * * . . / lib / md013 . js * * * !
\ * * * * * * * * * * * * * * * * * * * * * * * /
2021-01-05 20:55:09 -08:00
/***/ ( ( module , _ _unused _webpack _exports , _ _webpack _require _ _ ) => {
2019-10-02 20:10:42 -07:00
"use strict" ;
2021-01-05 20:55:09 -08:00
// @ts-check
2022-06-02 21:42:48 -07:00
const { addErrorDetailIf , filterTokens , forEachHeading , forEachLine , includesSorted , linkReferenceDefinitionRe } = _ _webpack _require _ _ ( /*! ../helpers */ "../helpers/helpers.js" ) ;
const { lineMetadata } = _ _webpack _require _ _ ( /*! ./cache */ "../lib/cache.js" ) ;
const longLineRePrefix = "^.{" ;
const longLineRePostfixRelaxed = "}.*\\s.*$" ;
const longLineRePostfixStrict = "}.+$" ;
const linkOrImageOnlyLineRe = /^[es]*(lT?L|I)[ES]*$/ ;
const sternModeRe = /^([#>\s]*\s)?\S*$/ ;
const tokenTypeMap = {
2019-10-02 20:10:42 -07:00
"em_open" : "e" ,
"em_close" : "E" ,
2020-01-27 19:19:34 -08:00
"image" : "I" ,
2019-10-02 20:10:42 -07:00
"link_open" : "l" ,
"link_close" : "L" ,
"strong_open" : "s" ,
"strong_close" : "S" ,
"text" : "T"
} ;
module . exports = {
"names" : [ "MD013" , "line-length" ] ,
"description" : "Line length" ,
"tags" : [ "line_length" ] ,
"function" : function MD013 ( params , onError ) {
2022-06-02 21:42:48 -07:00
const lineLength = Number ( params . config . line _length || 80 ) ;
const headingLineLength = Number ( params . config . heading _line _length || lineLength ) ;
const codeLineLength = Number ( params . config . code _block _line _length || lineLength ) ;
const strict = ! ! params . config . strict ;
const stern = ! ! params . config . stern ;
const longLineRePostfix = ( strict || stern ) ? longLineRePostfixStrict : longLineRePostfixRelaxed ;
const longLineRe = new RegExp ( longLineRePrefix + lineLength + longLineRePostfix ) ;
const longHeadingLineRe = new RegExp ( longLineRePrefix + headingLineLength + longLineRePostfix ) ;
const longCodeLineRe = new RegExp ( longLineRePrefix + codeLineLength + longLineRePostfix ) ;
const codeBlocks = params . config . code _blocks ;
const includeCodeBlocks = ( codeBlocks === undefined ) ? true : ! ! codeBlocks ;
const tables = params . config . tables ;
const includeTables = ( tables === undefined ) ? true : ! ! tables ;
let headings = params . config . headings ;
2019-10-02 20:10:42 -07:00
if ( headings === undefined ) {
headings = params . config . headers ;
}
2022-06-02 21:42:48 -07:00
const includeHeadings = ( headings === undefined ) ? true : ! ! headings ;
const headingLineNumbers = [ ] ;
forEachHeading ( params , ( heading ) => {
2019-10-02 20:10:42 -07:00
headingLineNumbers . push ( heading . lineNumber ) ;
} ) ;
2022-06-02 21:42:48 -07:00
const linkOnlyLineNumbers = [ ] ;
filterTokens ( params , "inline" , ( token ) => {
let childTokenTypes = "" ;
2022-06-08 22:10:27 -07:00
for ( const child of token . children ) {
2019-10-02 20:10:42 -07:00
if ( child . type !== "text" || child . content !== "" ) {
childTokenTypes += tokenTypeMap [ child . type ] || "x" ;
}
2022-06-08 22:10:27 -07:00
}
2020-01-27 19:19:34 -08:00
if ( linkOrImageOnlyLineRe . test ( childTokenTypes ) ) {
2019-10-02 20:10:42 -07:00
linkOnlyLineNumbers . push ( token . lineNumber ) ;
}
} ) ;
2022-06-02 21:42:48 -07:00
forEachLine ( lineMetadata ( ) , ( line , lineIndex , inCode , onFence , inTable ) => {
const lineNumber = lineIndex + 1 ;
const isHeading = includesSorted ( headingLineNumbers , lineNumber ) ;
const length = inCode ?
2019-10-02 20:10:42 -07:00
codeLineLength :
( isHeading ? headingLineLength : lineLength ) ;
2022-06-02 21:42:48 -07:00
const lengthRe = inCode ?
2019-10-02 20:10:42 -07:00
longCodeLineRe :
( isHeading ? longHeadingLineRe : longLineRe ) ;
if ( ( includeCodeBlocks || ! inCode ) &&
( includeTables || ! inTable ) &&
( includeHeadings || ! isHeading ) &&
2019-12-14 13:50:48 -08:00
( strict ||
2020-04-11 13:54:46 -07:00
( ! ( stern && sternModeRe . test ( line ) ) &&
! includesSorted ( linkOnlyLineNumbers , lineNumber ) &&
2022-06-01 20:23:08 -07:00
! linkReferenceDefinitionRe . test ( line ) ) ) &&
2019-12-14 13:50:48 -08:00
lengthRe . test ( line ) ) {
addErrorDetailIf ( onError , lineNumber , length , line . length , null , null , [ length + 1 , line . length - length ] ) ;
2019-10-02 20:10:42 -07:00
}
} ) ;
}
} ;
2021-01-05 20:55:09 -08:00
/***/ } ) ,
2021-01-06 19:45:15 -08:00
/***/ "../lib/md014.js" :
/ * ! * * * * * * * * * * * * * * * * * * * * * * * ! * \
! * * * . . / lib / md014 . js * * * !
\ * * * * * * * * * * * * * * * * * * * * * * * /
2021-01-05 20:55:09 -08:00
/***/ ( ( module , _ _unused _webpack _exports , _ _webpack _require _ _ ) => {
2019-10-02 20:10:42 -07:00
"use strict" ;
2021-01-05 20:55:09 -08:00
// @ts-check
2022-06-02 21:42:48 -07:00
const { addErrorContext , filterTokens } = _ _webpack _require _ _ ( /*! ../helpers */ "../helpers/helpers.js" ) ;
const dollarCommandRe = /^(\s*)(\$\s+)/ ;
2019-10-02 20:10:42 -07:00
module . exports = {
"names" : [ "MD014" , "commands-show-output" ] ,
"description" : "Dollar signs used before commands without showing output" ,
"tags" : [ "code" ] ,
"function" : function MD014 ( params , onError ) {
2022-06-08 22:10:27 -07:00
for ( const type of [ "code_block" , "fence" ] ) {
2022-06-02 21:42:48 -07:00
filterTokens ( params , type , ( token ) => {
const margin = ( token . type === "fence" ) ? 1 : 0 ;
const dollarInstances = [ ] ;
let allDollars = true ;
for ( let i = token . map [ 0 ] + margin ; i < token . map [ 1 ] - margin ; i ++ ) {
const line = params . lines [ i ] ;
const lineTrim = line . trim ( ) ;
2020-01-27 19:19:34 -08:00
if ( lineTrim ) {
2022-06-02 21:42:48 -07:00
const match = dollarCommandRe . exec ( line ) ;
2020-01-27 19:19:34 -08:00
if ( match ) {
2022-06-02 21:42:48 -07:00
const column = match [ 1 ] . length + 1 ;
const length = match [ 2 ] . length ;
2021-11-13 12:40:51 -08:00
dollarInstances . push ( [ i , lineTrim , column , length ] ) ;
2020-01-27 19:19:34 -08:00
}
else {
allDollars = false ;
}
2019-10-02 20:10:42 -07:00
}
2020-01-27 19:19:34 -08:00
}
if ( allDollars ) {
2022-06-08 22:10:27 -07:00
for ( const instance of dollarInstances ) {
2022-06-02 21:42:48 -07:00
const [ i , lineTrim , column , length ] = instance ;
2020-01-27 19:19:34 -08:00
addErrorContext ( onError , i + 1 , lineTrim , null , null , [ column , length ] , {
"editColumn" : column ,
"deleteCount" : length
} ) ;
2022-06-08 22:10:27 -07:00
}
2020-01-27 19:19:34 -08:00
}
2019-10-02 20:10:42 -07:00
} ) ;
2022-06-08 22:10:27 -07:00
}
2019-10-02 20:10:42 -07:00
}
} ;
2021-01-05 20:55:09 -08:00
/***/ } ) ,
2021-01-06 19:45:15 -08:00
/***/ "../lib/md018.js" :
/ * ! * * * * * * * * * * * * * * * * * * * * * * * ! * \
! * * * . . / lib / md018 . js * * * !
\ * * * * * * * * * * * * * * * * * * * * * * * /
2021-01-05 20:55:09 -08:00
/***/ ( ( module , _ _unused _webpack _exports , _ _webpack _require _ _ ) => {
2019-10-02 20:10:42 -07:00
"use strict" ;
2021-01-05 20:55:09 -08:00
// @ts-check
2022-06-02 21:42:48 -07:00
const { addErrorContext , forEachLine } = _ _webpack _require _ _ ( /*! ../helpers */ "../helpers/helpers.js" ) ;
const { lineMetadata } = _ _webpack _require _ _ ( /*! ./cache */ "../lib/cache.js" ) ;
2019-10-02 20:10:42 -07:00
module . exports = {
"names" : [ "MD018" , "no-missing-space-atx" ] ,
"description" : "No space after hash on atx style heading" ,
"tags" : [ "headings" , "headers" , "atx" , "spaces" ] ,
"function" : function MD018 ( params , onError ) {
2022-06-02 21:42:48 -07:00
forEachLine ( lineMetadata ( ) , ( line , lineIndex , inCode ) => {
2020-04-11 13:54:46 -07:00
if ( ! inCode &&
2021-02-03 22:05:07 -08:00
/^#+[^# \t]/ . test ( line ) &&
2020-04-11 13:54:46 -07:00
! /#\s*$/ . test ( line ) &&
! line . startsWith ( "#️⃣" ) ) {
2022-06-02 21:42:48 -07:00
const hashCount = /^#+/ . exec ( line ) [ 0 ] . length ;
2019-10-02 20:10:42 -07:00
addErrorContext ( onError , lineIndex + 1 , line . trim ( ) , null , null , [ 1 , hashCount + 1 ] , {
"editColumn" : hashCount + 1 ,
"insertText" : " "
} ) ;
}
} ) ;
}
} ;
2021-01-05 20:55:09 -08:00
/***/ } ) ,
2021-01-06 19:45:15 -08:00
/***/ "../lib/md019.js" :
/ * ! * * * * * * * * * * * * * * * * * * * * * * * ! * \
! * * * . . / lib / md019 . js * * * !
\ * * * * * * * * * * * * * * * * * * * * * * * /
2021-01-05 20:55:09 -08:00
/***/ ( ( module , _ _unused _webpack _exports , _ _webpack _require _ _ ) => {
2019-10-02 20:10:42 -07:00
"use strict" ;
2021-01-05 20:55:09 -08:00
// @ts-check
2022-06-02 21:42:48 -07:00
const { addErrorContext , filterTokens , headingStyleFor } = _ _webpack _require _ _ ( /*! ../helpers */ "../helpers/helpers.js" ) ;
2019-10-02 20:10:42 -07:00
module . exports = {
"names" : [ "MD019" , "no-multiple-space-atx" ] ,
"description" : "Multiple spaces after hash on atx style heading" ,
"tags" : [ "headings" , "headers" , "atx" , "spaces" ] ,
"function" : function MD019 ( params , onError ) {
2022-06-02 21:42:48 -07:00
filterTokens ( params , "heading_open" , ( token ) => {
2019-10-02 20:10:42 -07:00
if ( headingStyleFor ( token ) === "atx" ) {
2022-06-02 21:42:48 -07:00
const { line , lineNumber } = token ;
const match = /^(#+)([ \t]{2,})(?:\S)/ . exec ( line ) ;
2019-10-02 20:10:42 -07:00
if ( match ) {
2022-06-02 21:42:48 -07:00
const [ , { "length" : hashLength } , { "length" : spacesLength } ] = match ;
2019-10-02 20:10:42 -07:00
addErrorContext ( onError , lineNumber , line . trim ( ) , null , null , [ 1 , hashLength + spacesLength + 1 ] , {
"editColumn" : hashLength + 1 ,
"deleteCount" : spacesLength - 1
} ) ;
}
}
} ) ;
}
} ;
2021-01-05 20:55:09 -08:00
/***/ } ) ,
2021-01-06 19:45:15 -08:00
/***/ "../lib/md020.js" :
/ * ! * * * * * * * * * * * * * * * * * * * * * * * ! * \
! * * * . . / lib / md020 . js * * * !
\ * * * * * * * * * * * * * * * * * * * * * * * /
2021-01-05 20:55:09 -08:00
/***/ ( ( module , _ _unused _webpack _exports , _ _webpack _require _ _ ) => {
2019-10-02 20:10:42 -07:00
"use strict" ;
2021-01-05 20:55:09 -08:00
// @ts-check
2022-06-02 21:42:48 -07:00
const { addErrorContext , forEachLine } = _ _webpack _require _ _ ( /*! ../helpers */ "../helpers/helpers.js" ) ;
const { lineMetadata } = _ _webpack _require _ _ ( /*! ./cache */ "../lib/cache.js" ) ;
2019-10-02 20:10:42 -07:00
module . exports = {
"names" : [ "MD020" , "no-missing-space-closed-atx" ] ,
"description" : "No space inside hashes on closed atx style heading" ,
"tags" : [ "headings" , "headers" , "atx_closed" , "spaces" ] ,
"function" : function MD020 ( params , onError ) {
2022-06-02 21:42:48 -07:00
forEachLine ( lineMetadata ( ) , ( line , lineIndex , inCode ) => {
2019-10-02 20:10:42 -07:00
if ( ! inCode ) {
2022-06-02 21:42:48 -07:00
const match = /^(#+)([ \t]*)([^#]*?[^#\\])([ \t]*)((?:\\#)?)(#+)(\s*)$/ . exec ( line ) ;
2019-10-02 20:10:42 -07:00
if ( match ) {
2022-06-02 21:42:48 -07:00
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 } ` : "" ;
2019-10-02 20:10:42 -07:00
if ( left || right ) {
2022-06-02 21:42:48 -07:00
const range = left ?
2019-10-02 20:10:42 -07:00
[
1 ,
leftHashLength + 1
] :
[
line . length - trailSpaceLength - rightHashLength ,
rightHashLength + 1
] ;
addErrorContext ( onError , lineIndex + 1 , line . trim ( ) , left , right , range , {
"editColumn" : 1 ,
"deleteCount" : line . length ,
2022-06-02 21:42:48 -07:00
"insertText" : ` ${ leftHash } ${ content } ${ rightEscapeReplacement } ${ rightHash } `
2019-10-02 20:10:42 -07:00
} ) ;
}
}
}
} ) ;
}
} ;
2021-01-05 20:55:09 -08:00
/***/ } ) ,
2021-01-06 19:45:15 -08:00
/***/ "../lib/md021.js" :
/ * ! * * * * * * * * * * * * * * * * * * * * * * * ! * \
! * * * . . / lib / md021 . js * * * !
\ * * * * * * * * * * * * * * * * * * * * * * * /
2021-01-05 20:55:09 -08:00
/***/ ( ( module , _ _unused _webpack _exports , _ _webpack _require _ _ ) => {
2019-10-02 20:10:42 -07:00
"use strict" ;
2021-01-05 20:55:09 -08:00
// @ts-check
2022-06-02 21:42:48 -07:00
const { addErrorContext , filterTokens , headingStyleFor } = _ _webpack _require _ _ ( /*! ../helpers */ "../helpers/helpers.js" ) ;
const closedAtxRe = /^(#+)([ \t]+)([^ \t]|[^ \t].*[^ \t])([ \t]+)(#+)(\s*)$/ ;
2019-10-02 20:10:42 -07:00
module . exports = {
"names" : [ "MD021" , "no-multiple-space-closed-atx" ] ,
"description" : "Multiple spaces inside hashes on closed atx style heading" ,
"tags" : [ "headings" , "headers" , "atx_closed" , "spaces" ] ,
"function" : function MD021 ( params , onError ) {
2022-06-02 21:42:48 -07:00
filterTokens ( params , "heading_open" , ( token ) => {
2019-10-02 20:10:42 -07:00
if ( headingStyleFor ( token ) === "atx_closed" ) {
2022-06-02 21:42:48 -07:00
const { line , lineNumber } = token ;
const match = closedAtxRe . exec ( line ) ;
2019-10-02 20:10:42 -07:00
if ( match ) {
2022-06-02 21:42:48 -07:00
const [ , leftHash , { "length" : leftSpaceLength } , content , { "length" : rightSpaceLength } , rightHash , { "length" : trailSpaceLength } ] = match ;
const left = leftSpaceLength > 1 ;
const right = rightSpaceLength > 1 ;
2019-10-02 20:10:42 -07:00
if ( left || right ) {
2022-06-02 21:42:48 -07:00
const length = line . length ;
const leftHashLength = leftHash . length ;
const rightHashLength = rightHash . length ;
const range = left ?
2019-10-02 20:10:42 -07:00
[
1 ,
leftHashLength + leftSpaceLength + 1
] :
[
2021-11-13 12:40:51 -08:00
length - trailSpaceLength - rightHashLength - rightSpaceLength ,
2019-10-02 20:10:42 -07:00
rightSpaceLength + rightHashLength + 1
] ;
addErrorContext ( onError , lineNumber , line . trim ( ) , left , right , range , {
"editColumn" : 1 ,
2021-11-13 12:40:51 -08:00
"deleteCount" : length ,
2022-06-02 21:42:48 -07:00
"insertText" : ` ${ leftHash } ${ content } ${ rightHash } `
2019-10-02 20:10:42 -07:00
} ) ;
}
}
}
} ) ;
}
} ;
2021-01-05 20:55:09 -08:00
/***/ } ) ,
2021-01-06 19:45:15 -08:00
/***/ "../lib/md022.js" :
/ * ! * * * * * * * * * * * * * * * * * * * * * * * ! * \
! * * * . . / lib / md022 . js * * * !
\ * * * * * * * * * * * * * * * * * * * * * * * /
2021-01-05 20:55:09 -08:00
/***/ ( ( module , _ _unused _webpack _exports , _ _webpack _require _ _ ) => {
2019-10-02 20:10:42 -07:00
"use strict" ;
2021-01-05 20:55:09 -08:00
// @ts-check
2022-06-02 21:42:48 -07:00
const { addErrorDetailIf , filterTokens , isBlankLine } = _ _webpack _require _ _ ( /*! ../helpers */ "../helpers/helpers.js" ) ;
2019-10-02 20:10:42 -07:00
module . exports = {
"names" : [ "MD022" , "blanks-around-headings" , "blanks-around-headers" ] ,
"description" : "Headings should be surrounded by blank lines" ,
"tags" : [ "headings" , "headers" , "blank_lines" ] ,
"function" : function MD022 ( params , onError ) {
2022-06-02 21:42:48 -07:00
let linesAbove = params . config . lines _above ;
2020-01-27 19:19:34 -08:00
linesAbove = Number ( ( linesAbove === undefined ) ? 1 : linesAbove ) ;
2022-06-02 21:42:48 -07:00
let linesBelow = params . config . lines _below ;
2020-01-27 19:19:34 -08:00
linesBelow = Number ( ( linesBelow === undefined ) ? 1 : linesBelow ) ;
2022-06-02 21:42:48 -07:00
const { lines } = params ;
filterTokens ( params , "heading_open" , ( token ) => {
const [ topIndex , nextIndex ] = token . map ;
let actualAbove = 0 ;
for ( let i = 0 ; i < linesAbove ; i ++ ) {
2019-10-02 20:10:42 -07:00
if ( isBlankLine ( lines [ topIndex - i - 1 ] ) ) {
actualAbove ++ ;
}
}
addErrorDetailIf ( onError , topIndex + 1 , linesAbove , actualAbove , "Above" , lines [ topIndex ] . trim ( ) , null , {
"insertText" : "" . padEnd ( linesAbove - actualAbove , "\n" )
} ) ;
2022-06-02 21:42:48 -07:00
let actualBelow = 0 ;
for ( let i = 0 ; i < linesBelow ; i ++ ) {
2019-10-02 20:10:42 -07:00
if ( isBlankLine ( lines [ nextIndex + i ] ) ) {
actualBelow ++ ;
}
}
addErrorDetailIf ( onError , topIndex + 1 , linesBelow , actualBelow , "Below" , lines [ topIndex ] . trim ( ) , null , {
"lineNumber" : nextIndex + 1 ,
"insertText" : "" . padEnd ( linesBelow - actualBelow , "\n" )
} ) ;
} ) ;
}
} ;
2021-01-05 20:55:09 -08:00
/***/ } ) ,
2021-01-06 19:45:15 -08:00
/***/ "../lib/md023.js" :
/ * ! * * * * * * * * * * * * * * * * * * * * * * * ! * \
! * * * . . / lib / md023 . js * * * !
\ * * * * * * * * * * * * * * * * * * * * * * * /
2021-01-05 20:55:09 -08:00
/***/ ( ( module , _ _unused _webpack _exports , _ _webpack _require _ _ ) => {
2019-10-02 20:10:42 -07:00
"use strict" ;
2021-01-05 20:55:09 -08:00
// @ts-check
2022-06-02 21:42:48 -07:00
const { addErrorContext , filterTokens } = _ _webpack _require _ _ ( /*! ../helpers */ "../helpers/helpers.js" ) ;
const spaceBeforeHeadingRe = /^((?:\s+)|(?:[>\s]+\s\s))[^>\s]/ ;
2019-10-02 20:10:42 -07:00
module . exports = {
"names" : [ "MD023" , "heading-start-left" , "header-start-left" ] ,
"description" : "Headings must start at the beginning of the line" ,
"tags" : [ "headings" , "headers" , "spaces" ] ,
"function" : function MD023 ( params , onError ) {
filterTokens ( params , "heading_open" , function forToken ( token ) {
2022-06-02 21:42:48 -07:00
const { lineNumber , line } = token ;
const match = line . match ( spaceBeforeHeadingRe ) ;
2019-10-02 20:10:42 -07:00
if ( match ) {
2022-06-02 21:42:48 -07:00
const [ prefixAndFirstChar , prefix ] = match ;
let deleteCount = prefix . length ;
const prefixLengthNoSpace = prefix . trimEnd ( ) . length ;
2019-10-02 20:10:42 -07:00
if ( prefixLengthNoSpace ) {
deleteCount -= prefixLengthNoSpace - 1 ;
}
addErrorContext ( onError , lineNumber , line , null , null , [ 1 , prefixAndFirstChar . length ] , {
"editColumn" : prefixLengthNoSpace + 1 ,
"deleteCount" : deleteCount
} ) ;
}
} ) ;
}
} ;
2021-01-05 20:55:09 -08:00
/***/ } ) ,
2021-01-06 19:45:15 -08:00
/***/ "../lib/md024.js" :
/ * ! * * * * * * * * * * * * * * * * * * * * * * * ! * \
! * * * . . / lib / md024 . js * * * !
\ * * * * * * * * * * * * * * * * * * * * * * * /
2021-01-05 20:55:09 -08:00
/***/ ( ( module , _ _unused _webpack _exports , _ _webpack _require _ _ ) => {
2019-10-02 20:10:42 -07:00
"use strict" ;
2021-01-05 20:55:09 -08:00
// @ts-check
2022-06-02 21:42:48 -07:00
const { addErrorContext , forEachHeading } = _ _webpack _require _ _ ( /*! ../helpers */ "../helpers/helpers.js" ) ;
2019-10-02 20:10:42 -07:00
module . exports = {
"names" : [ "MD024" , "no-duplicate-heading" , "no-duplicate-header" ] ,
"description" : "Multiple headings with the same content" ,
"tags" : [ "headings" , "headers" ] ,
"function" : function MD024 ( params , onError ) {
2022-06-02 21:42:48 -07:00
const siblingsOnly = ! ! params . config . siblings _only ||
2020-01-27 19:19:34 -08:00
! ! params . config . allow _different _nesting || false ;
2022-06-02 21:42:48 -07:00
const knownContents = [ null , [ ] ] ;
let lastLevel = 1 ;
let knownContent = knownContents [ lastLevel ] ;
forEachHeading ( params , ( heading , content ) => {
2019-10-02 20:10:42 -07:00
if ( siblingsOnly ) {
2022-06-02 21:42:48 -07:00
const newLevel = heading . tag . slice ( 1 ) ;
2019-10-02 20:10:42 -07:00
while ( lastLevel < newLevel ) {
lastLevel ++ ;
knownContents [ lastLevel ] = [ ] ;
}
while ( lastLevel > newLevel ) {
knownContents [ lastLevel ] = [ ] ;
lastLevel -- ;
}
knownContent = knownContents [ newLevel ] ;
}
if ( knownContent . includes ( content ) ) {
addErrorContext ( onError , heading . lineNumber , heading . line . trim ( ) ) ;
}
else {
knownContent . push ( content ) ;
}
} ) ;
}
} ;
2021-01-05 20:55:09 -08:00
/***/ } ) ,
2021-01-06 19:45:15 -08:00
/***/ "../lib/md025.js" :
/ * ! * * * * * * * * * * * * * * * * * * * * * * * ! * \
! * * * . . / lib / md025 . js * * * !
\ * * * * * * * * * * * * * * * * * * * * * * * /
2021-01-05 20:55:09 -08:00
/***/ ( ( module , _ _unused _webpack _exports , _ _webpack _require _ _ ) => {
2019-10-02 20:10:42 -07:00
"use strict" ;
2021-01-05 20:55:09 -08:00
// @ts-check
2022-06-02 21:42:48 -07:00
const { addErrorContext , filterTokens , frontMatterHasTitle } = _ _webpack _require _ _ ( /*! ../helpers */ "../helpers/helpers.js" ) ;
2019-10-02 20:10:42 -07:00
module . exports = {
"names" : [ "MD025" , "single-title" , "single-h1" ] ,
2020-12-28 13:28:38 -08:00
"description" : "Multiple top-level headings in the same document" ,
2019-10-02 20:10:42 -07:00
"tags" : [ "headings" , "headers" ] ,
"function" : function MD025 ( params , onError ) {
2022-06-02 21:42:48 -07:00
const level = Number ( params . config . level || 1 ) ;
const tag = "h" + level ;
const foundFrontMatterTitle = frontMatterHasTitle ( params . frontMatterLines , params . config . front _matter _title ) ;
let hasTopLevelHeading = false ;
2019-10-02 20:10:42 -07:00
filterTokens ( params , "heading_open" , function forToken ( token ) {
if ( token . tag === tag ) {
if ( hasTopLevelHeading || foundFrontMatterTitle ) {
addErrorContext ( onError , token . lineNumber , token . line . trim ( ) ) ;
}
else if ( token . lineNumber === 1 ) {
hasTopLevelHeading = true ;
}
}
} ) ;
}
} ;
2021-01-05 20:55:09 -08:00
/***/ } ) ,
2021-01-06 19:45:15 -08:00
/***/ "../lib/md026.js" :
/ * ! * * * * * * * * * * * * * * * * * * * * * * * ! * \
! * * * . . / lib / md026 . js * * * !
\ * * * * * * * * * * * * * * * * * * * * * * * /
2021-01-05 20:55:09 -08:00
/***/ ( ( module , _ _unused _webpack _exports , _ _webpack _require _ _ ) => {
2019-10-02 20:10:42 -07:00
"use strict" ;
2021-01-05 20:55:09 -08:00
// @ts-check
2022-06-02 21:42:48 -07:00
const { addError , allPunctuationNoQuestion , escapeForRegExp , forEachHeading } = _ _webpack _require _ _ ( /*! ../helpers */ "../helpers/helpers.js" ) ;
const endOfLineHtmlEntityRe = /&#?[0-9a-zA-Z]+;$/ ;
2019-10-02 20:10:42 -07:00
module . exports = {
"names" : [ "MD026" , "no-trailing-punctuation" ] ,
"description" : "Trailing punctuation in heading" ,
"tags" : [ "headings" , "headers" ] ,
"function" : function MD026 ( params , onError ) {
2022-06-02 21:42:48 -07:00
let punctuation = params . config . punctuation ;
2020-11-24 16:37:11 -08:00
punctuation = String ( ( punctuation === undefined ) ? allPunctuationNoQuestion : punctuation ) ;
2022-06-02 21:42:48 -07:00
const trailingPunctuationRe = new RegExp ( "\\s*[" + escapeForRegExp ( punctuation ) + "]+$" ) ;
forEachHeading ( params , ( heading ) => {
const { line , lineNumber } = heading ;
const trimmedLine = line . replace ( /([^\s#])[\s#]+$/ , "$1" ) ;
const match = trailingPunctuationRe . exec ( trimmedLine ) ;
2020-11-24 16:37:11 -08:00
if ( match && ! endOfLineHtmlEntityRe . test ( trimmedLine ) ) {
2022-06-02 21:42:48 -07:00
const fullMatch = match [ 0 ] ;
const column = match . index + 1 ;
const length = fullMatch . length ;
addError ( onError , lineNumber , ` Punctuation: ' ${ fullMatch } ' ` , null , [ column , length ] , {
2019-10-02 20:10:42 -07:00
"editColumn" : column ,
2021-11-13 12:40:51 -08:00
"deleteCount" : length
2019-10-02 20:10:42 -07:00
} ) ;
}
} ) ;
}
} ;
2021-01-05 20:55:09 -08:00
/***/ } ) ,
2021-01-06 19:45:15 -08:00
/***/ "../lib/md027.js" :
/ * ! * * * * * * * * * * * * * * * * * * * * * * * ! * \
! * * * . . / lib / md027 . js * * * !
\ * * * * * * * * * * * * * * * * * * * * * * * /
2021-01-05 20:55:09 -08:00
/***/ ( ( module , _ _unused _webpack _exports , _ _webpack _require _ _ ) => {
2019-10-02 20:10:42 -07:00
"use strict" ;
2021-01-05 20:55:09 -08:00
// @ts-check
2022-06-02 21:42:48 -07:00
const { addErrorContext , newLineRe } = _ _webpack _require _ _ ( /*! ../helpers */ "../helpers/helpers.js" ) ;
const spaceAfterBlockQuoteRe = /^((?:\s*>)+)(\s{2,})\S/ ;
2019-10-02 20:10:42 -07:00
module . exports = {
"names" : [ "MD027" , "no-multiple-space-blockquote" ] ,
"description" : "Multiple spaces after blockquote symbol" ,
"tags" : [ "blockquote" , "whitespace" , "indentation" ] ,
"function" : function MD027 ( params , onError ) {
2022-06-02 21:42:48 -07:00
let blockquoteNesting = 0 ;
let listItemNesting = 0 ;
2022-06-08 22:10:27 -07:00
for ( const token of params . tokens ) {
2022-06-02 21:42:48 -07:00
const { content , lineNumber , type } = token ;
2019-10-02 20:10:42 -07:00
if ( type === "blockquote_open" ) {
blockquoteNesting ++ ;
}
else if ( type === "blockquote_close" ) {
blockquoteNesting -- ;
}
else if ( type === "list_item_open" ) {
listItemNesting ++ ;
}
else if ( type === "list_item_close" ) {
listItemNesting -- ;
}
else if ( ( type === "inline" ) && blockquoteNesting ) {
2022-06-02 21:42:48 -07:00
const lineCount = content . split ( newLineRe ) . length ;
for ( let i = 0 ; i < lineCount ; i ++ ) {
const line = params . lines [ lineNumber + i - 1 ] ;
const match = line . match ( spaceAfterBlockQuoteRe ) ;
2019-10-02 20:10:42 -07:00
if ( match ) {
2022-06-02 21:42:48 -07:00
const [ fullMatch , { "length" : blockquoteLength } , { "length" : spaceLength } ] = match ;
2019-10-02 20:10:42 -07:00
if ( ! listItemNesting || ( fullMatch [ fullMatch . length - 1 ] === ">" ) ) {
addErrorContext ( onError , lineNumber + i , line , null , null , [ 1 , fullMatch . length ] , {
"editColumn" : blockquoteLength + 1 ,
"deleteCount" : spaceLength - 1
} ) ;
}
}
}
}
2022-06-08 22:10:27 -07:00
}
2019-10-02 20:10:42 -07:00
}
} ;
2021-01-05 20:55:09 -08:00
/***/ } ) ,
2021-01-06 19:45:15 -08:00
/***/ "../lib/md028.js" :
/ * ! * * * * * * * * * * * * * * * * * * * * * * * ! * \
! * * * . . / lib / md028 . js * * * !
\ * * * * * * * * * * * * * * * * * * * * * * * /
2021-01-05 20:55:09 -08:00
/***/ ( ( module , _ _unused _webpack _exports , _ _webpack _require _ _ ) => {
2019-10-02 20:10:42 -07:00
"use strict" ;
2021-01-05 20:55:09 -08:00
// @ts-check
2022-06-02 21:42:48 -07:00
const { addError } = _ _webpack _require _ _ ( /*! ../helpers */ "../helpers/helpers.js" ) ;
2019-10-02 20:10:42 -07:00
module . exports = {
"names" : [ "MD028" , "no-blanks-blockquote" ] ,
"description" : "Blank line inside blockquote" ,
"tags" : [ "blockquote" , "whitespace" ] ,
"function" : function MD028 ( params , onError ) {
2022-06-02 21:42:48 -07:00
let prevToken = { } ;
let prevLineNumber = null ;
2022-06-08 22:10:27 -07:00
for ( const token of params . tokens ) {
2019-10-02 20:10:42 -07:00
if ( ( token . type === "blockquote_open" ) &&
( prevToken . type === "blockquote_close" ) ) {
2022-06-02 21:42:48 -07:00
for ( let lineNumber = prevLineNumber ; lineNumber < token . lineNumber ; lineNumber ++ ) {
2020-11-24 16:37:11 -08:00
addError ( onError , lineNumber ) ;
2019-10-02 20:10:42 -07:00
}
}
prevToken = token ;
if ( token . type === "blockquote_open" ) {
prevLineNumber = token . map [ 1 ] + 1 ;
}
2022-06-08 22:10:27 -07:00
}
2019-10-02 20:10:42 -07:00
}
} ;
2021-01-05 20:55:09 -08:00
/***/ } ) ,
2021-01-06 19:45:15 -08:00
/***/ "../lib/md029.js" :
/ * ! * * * * * * * * * * * * * * * * * * * * * * * ! * \
! * * * . . / lib / md029 . js * * * !
\ * * * * * * * * * * * * * * * * * * * * * * * /
2021-01-05 20:55:09 -08:00
/***/ ( ( module , _ _unused _webpack _exports , _ _webpack _require _ _ ) => {
2019-10-02 20:10:42 -07:00
"use strict" ;
2021-01-05 20:55:09 -08:00
// @ts-check
2022-06-02 21:42:48 -07:00
const { addErrorDetailIf , listItemMarkerRe , orderedListItemMarkerRe , rangeFromRegExp } = _ _webpack _require _ _ ( /*! ../helpers */ "../helpers/helpers.js" ) ;
const { flattenedLists } = _ _webpack _require _ _ ( /*! ./cache */ "../lib/cache.js" ) ;
const listStyleExamples = {
2019-10-02 20:10:42 -07:00
"one" : "1/1/1" ,
"ordered" : "1/2/3" ,
"zero" : "0/0/0"
} ;
module . exports = {
"names" : [ "MD029" , "ol-prefix" ] ,
"description" : "Ordered list item prefix" ,
"tags" : [ "ol" ] ,
"function" : function MD029 ( params , onError ) {
2022-06-02 21:42:48 -07:00
const style = String ( params . config . style || "one_or_ordered" ) ;
2022-06-08 22:10:27 -07:00
const filteredLists = flattenedLists ( ) . filter ( ( list ) => ! list . unordered ) ;
for ( const list of filteredLists ) {
2022-06-02 21:42:48 -07:00
const { items } = list ;
let current = 1 ;
let incrementing = false ;
2020-04-11 13:54:46 -07:00
// Check for incrementing number pattern 1/2/3 or 0/1/2
if ( items . length >= 2 ) {
2022-06-02 21:42:48 -07:00
const first = orderedListItemMarkerRe . exec ( items [ 0 ] . line ) ;
const second = orderedListItemMarkerRe . exec ( items [ 1 ] . line ) ;
2020-04-11 13:54:46 -07:00
if ( first && second ) {
2022-06-02 21:42:48 -07:00
const [ , firstNumber ] = first ;
const [ , secondNumber ] = second ;
2020-04-11 13:54:46 -07:00
if ( ( secondNumber !== "1" ) || ( firstNumber === "0" ) ) {
incrementing = true ;
if ( firstNumber === "0" ) {
current = 0 ;
}
2019-10-02 20:10:42 -07:00
}
2020-04-11 13:54:46 -07:00
}
}
// Determine effective style
2022-06-02 21:42:48 -07:00
let listStyle = style ;
2020-04-11 13:54:46 -07:00
if ( listStyle === "one_or_ordered" ) {
listStyle = incrementing ? "ordered" : "one" ;
}
// Force expected value for 0/0/0 and 1/1/1 patterns
if ( listStyle === "zero" ) {
current = 0 ;
2019-10-02 20:10:42 -07:00
}
2020-04-11 13:54:46 -07:00
else if ( listStyle === "one" ) {
current = 1 ;
}
// Validate each list item marker
2022-06-08 22:10:27 -07:00
for ( const item of items ) {
2022-06-02 21:42:48 -07:00
const match = orderedListItemMarkerRe . exec ( item . line ) ;
2020-04-11 13:54:46 -07:00
if ( match ) {
addErrorDetailIf ( onError , item . lineNumber , String ( current ) , match [ 1 ] , "Style: " + listStyleExamples [ listStyle ] , null , rangeFromRegExp ( item . line , listItemMarkerRe ) ) ;
if ( listStyle === "ordered" ) {
current ++ ;
}
}
2022-06-08 22:10:27 -07:00
}
}
2019-10-02 20:10:42 -07:00
}
} ;
2021-01-05 20:55:09 -08:00
/***/ } ) ,
2021-01-06 19:45:15 -08:00
/***/ "../lib/md030.js" :
/ * ! * * * * * * * * * * * * * * * * * * * * * * * ! * \
! * * * . . / lib / md030 . js * * * !
\ * * * * * * * * * * * * * * * * * * * * * * * /
2021-01-05 20:55:09 -08:00
/***/ ( ( module , _ _unused _webpack _exports , _ _webpack _require _ _ ) => {
2019-10-02 20:10:42 -07:00
"use strict" ;
2021-01-05 20:55:09 -08:00
// @ts-check
2022-06-02 21:42:48 -07:00
const { addErrorDetailIf } = _ _webpack _require _ _ ( /*! ../helpers */ "../helpers/helpers.js" ) ;
const { flattenedLists } = _ _webpack _require _ _ ( /*! ./cache */ "../lib/cache.js" ) ;
2019-10-02 20:10:42 -07:00
module . exports = {
"names" : [ "MD030" , "list-marker-space" ] ,
"description" : "Spaces after list markers" ,
"tags" : [ "ol" , "ul" , "whitespace" ] ,
"function" : function MD030 ( params , onError ) {
2022-06-02 21:42:48 -07:00
const ulSingle = Number ( params . config . ul _single || 1 ) ;
const olSingle = Number ( params . config . ol _single || 1 ) ;
const ulMulti = Number ( params . config . ul _multi || 1 ) ;
const olMulti = Number ( params . config . ol _multi || 1 ) ;
2022-06-08 22:10:27 -07:00
for ( const list of flattenedLists ( ) ) {
2022-06-02 21:42:48 -07:00
const lineCount = list . lastLineIndex - list . open . map [ 0 ] ;
const allSingle = lineCount === list . items . length ;
const expectedSpaces = list . unordered ?
2019-10-02 20:10:42 -07:00
( allSingle ? ulSingle : ulMulti ) :
( allSingle ? olSingle : olMulti ) ;
2022-06-08 22:10:27 -07:00
for ( const item of list . items ) {
2022-06-02 21:42:48 -07:00
const { line , lineNumber } = item ;
const match = /^[\s>]*\S+(\s*)/ . exec ( line ) ;
const [ { "length" : matchLength } , { "length" : actualSpaces } ] = match ;
2019-12-14 13:50:48 -08:00
if ( matchLength < line . length ) {
2022-06-02 21:42:48 -07:00
let fixInfo = null ;
2019-12-14 13:50:48 -08:00
if ( expectedSpaces !== actualSpaces ) {
fixInfo = {
"editColumn" : matchLength - actualSpaces + 1 ,
"deleteCount" : actualSpaces ,
"insertText" : "" . padEnd ( expectedSpaces )
} ;
}
addErrorDetailIf ( onError , lineNumber , expectedSpaces , actualSpaces , null , null , [ 1 , matchLength ] , fixInfo ) ;
2019-10-02 20:10:42 -07:00
}
2022-06-08 22:10:27 -07:00
}
}
2019-10-02 20:10:42 -07:00
}
} ;
2021-01-05 20:55:09 -08:00
/***/ } ) ,
2021-01-06 19:45:15 -08:00
/***/ "../lib/md031.js" :
/ * ! * * * * * * * * * * * * * * * * * * * * * * * ! * \
! * * * . . / lib / md031 . js * * * !
\ * * * * * * * * * * * * * * * * * * * * * * * /
2021-01-05 20:55:09 -08:00
/***/ ( ( module , _ _unused _webpack _exports , _ _webpack _require _ _ ) => {
2019-10-02 20:10:42 -07:00
"use strict" ;
2021-01-05 20:55:09 -08:00
// @ts-check
2022-06-02 21:42:48 -07:00
const { addErrorContext , forEachLine , isBlankLine } = _ _webpack _require _ _ ( /*! ../helpers */ "../helpers/helpers.js" ) ;
const { lineMetadata } = _ _webpack _require _ _ ( /*! ./cache */ "../lib/cache.js" ) ;
const codeFencePrefixRe = /^(.*?)[`~]/ ;
2019-10-02 20:10:42 -07:00
module . exports = {
"names" : [ "MD031" , "blanks-around-fences" ] ,
"description" : "Fenced code blocks should be surrounded by blank lines" ,
"tags" : [ "code" , "blank_lines" ] ,
"function" : function MD031 ( params , onError ) {
2022-06-02 21:42:48 -07:00
const listItems = params . config . list _items ;
const includeListItems = ( listItems === undefined ) ? true : ! ! listItems ;
const { lines } = params ;
forEachLine ( lineMetadata ( ) , ( line , i , inCode , onFence , inTable , inItem ) => {
const onTopFence = ( onFence > 0 ) ;
const onBottomFence = ( onFence < 0 ) ;
2019-10-02 20:10:42 -07:00
if ( ( includeListItems || ! inItem ) &&
( ( onTopFence && ! isBlankLine ( lines [ i - 1 ] ) ) ||
( onBottomFence && ! isBlankLine ( lines [ i + 1 ] ) ) ) ) {
2022-06-02 21:42:48 -07:00
const [ , prefix ] = line . match ( codeFencePrefixRe ) || [ ] ;
const fixInfo = ( prefix === undefined ) ? null : {
2019-10-02 20:10:42 -07:00
"lineNumber" : i + ( onTopFence ? 1 : 2 ) ,
2022-06-02 21:42:48 -07:00
"insertText" : ` ${ prefix . replace ( /[^>]/g , " " ) . trim ( ) } \n `
2020-10-20 20:16:49 -07:00
} ;
addErrorContext ( onError , i + 1 , lines [ i ] . trim ( ) , null , null , null , fixInfo ) ;
2019-10-02 20:10:42 -07:00
}
} ) ;
}
} ;
2021-01-05 20:55:09 -08:00
/***/ } ) ,
2021-01-06 19:45:15 -08:00
/***/ "../lib/md032.js" :
/ * ! * * * * * * * * * * * * * * * * * * * * * * * ! * \
! * * * . . / lib / md032 . js * * * !
\ * * * * * * * * * * * * * * * * * * * * * * * /
2021-01-05 20:55:09 -08:00
/***/ ( ( module , _ _unused _webpack _exports , _ _webpack _require _ _ ) => {
2019-10-02 20:10:42 -07:00
"use strict" ;
2021-01-05 20:55:09 -08:00
// @ts-check
2022-08-01 18:48:01 -07:00
const { addErrorContext , blockquotePrefixRe , isBlankLine } = _ _webpack _require _ _ ( /*! ../helpers */ "../helpers/helpers.js" ) ;
2022-06-02 21:42:48 -07:00
const { flattenedLists } = _ _webpack _require _ _ ( /*! ./cache */ "../lib/cache.js" ) ;
2019-10-02 20:10:42 -07:00
module . exports = {
"names" : [ "MD032" , "blanks-around-lists" ] ,
"description" : "Lists should be surrounded by blank lines" ,
"tags" : [ "bullet" , "ul" , "ol" , "blank_lines" ] ,
"function" : function MD032 ( params , onError ) {
2022-06-02 21:42:48 -07:00
const { lines } = params ;
2022-06-08 22:10:27 -07:00
const filteredLists = flattenedLists ( ) . filter ( ( list ) => ! list . nesting ) ;
for ( const list of filteredLists ) {
2022-06-02 21:42:48 -07:00
const firstIndex = list . open . map [ 0 ] ;
2019-10-02 20:10:42 -07:00
if ( ! isBlankLine ( lines [ firstIndex - 1 ] ) ) {
2022-06-02 21:42:48 -07:00
const line = lines [ firstIndex ] ;
2022-08-01 18:48:01 -07:00
const quotePrefix = line . match ( blockquotePrefixRe ) [ 0 ] . trimEnd ( ) ;
2019-10-02 20:10:42 -07:00
addErrorContext ( onError , firstIndex + 1 , line . trim ( ) , null , null , null , {
2022-06-02 21:42:48 -07:00
"insertText" : ` ${ quotePrefix } \n `
2019-10-02 20:10:42 -07:00
} ) ;
}
2022-06-02 21:42:48 -07:00
const lastIndex = list . lastLineIndex - 1 ;
2019-10-02 20:10:42 -07:00
if ( ! isBlankLine ( lines [ lastIndex + 1 ] ) ) {
2022-06-02 21:42:48 -07:00
const line = lines [ lastIndex ] ;
2022-08-01 18:48:01 -07:00
const quotePrefix = line . match ( blockquotePrefixRe ) [ 0 ] . trimEnd ( ) ;
2019-10-02 20:10:42 -07:00
addErrorContext ( onError , lastIndex + 1 , line . trim ( ) , null , null , null , {
"lineNumber" : lastIndex + 2 ,
2022-06-02 21:42:48 -07:00
"insertText" : ` ${ quotePrefix } \n `
2019-10-02 20:10:42 -07:00
} ) ;
}
2022-06-08 22:10:27 -07:00
}
2019-10-02 20:10:42 -07:00
}
} ;
2021-01-05 20:55:09 -08:00
/***/ } ) ,
2021-01-06 19:45:15 -08:00
/***/ "../lib/md033.js" :
/ * ! * * * * * * * * * * * * * * * * * * * * * * * ! * \
! * * * . . / lib / md033 . js * * * !
\ * * * * * * * * * * * * * * * * * * * * * * * /
2021-01-05 20:55:09 -08:00
/***/ ( ( module , _ _unused _webpack _exports , _ _webpack _require _ _ ) => {
2019-10-02 20:10:42 -07:00
"use strict" ;
2021-01-05 20:55:09 -08:00
// @ts-check
2022-06-02 22:17:32 -07:00
const { addError , forEachLine , htmlElementRe , withinAnyRange , unescapeMarkdown } = _ _webpack _require _ _ ( /*! ../helpers */ "../helpers/helpers.js" ) ;
2022-06-02 21:42:48 -07:00
const { codeBlockAndSpanRanges , lineMetadata } = _ _webpack _require _ _ ( /*! ./cache */ "../lib/cache.js" ) ;
const linkDestinationRe = /]\(\s*$/ ;
2019-10-02 20:10:42 -07:00
// See https://spec.commonmark.org/0.29/#autolinks
2022-06-02 21:42:48 -07:00
const emailAddressRe =
2019-10-02 20:10:42 -07:00
// eslint-disable-next-line max-len
/^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/ ;
module . exports = {
"names" : [ "MD033" , "no-inline-html" ] ,
"description" : "Inline HTML" ,
"tags" : [ "html" ] ,
"function" : function MD033 ( params , onError ) {
2022-06-02 21:42:48 -07:00
let allowedElements = params . config . allowed _elements ;
2020-01-27 19:19:34 -08:00
allowedElements = Array . isArray ( allowedElements ) ? allowedElements : [ ] ;
2022-06-02 21:42:48 -07:00
allowedElements = allowedElements . map ( ( element ) => element . toLowerCase ( ) ) ;
const exclusions = codeBlockAndSpanRanges ( ) ;
forEachLine ( lineMetadata ( ) , ( line , lineIndex , inCode ) => {
let match = null ;
2019-10-02 20:10:42 -07:00
// eslint-disable-next-line no-unmodified-loop-condition
2019-10-24 20:23:22 -07:00
while ( ! inCode && ( ( match = htmlElementRe . exec ( line ) ) !== null ) ) {
2022-06-02 21:42:48 -07:00
const [ tag , content , element ] = match ;
2019-10-02 20:10:42 -07:00
if ( ! allowedElements . includes ( element . toLowerCase ( ) ) &&
2019-10-24 20:23:22 -07:00
! tag . endsWith ( "\\>" ) &&
2021-10-21 13:13:42 +02:00
! emailAddressRe . test ( content ) &&
2022-06-02 22:17:32 -07:00
! withinAnyRange ( exclusions , lineIndex , match . index , match [ 0 ] . length ) ) {
2022-06-02 21:42:48 -07:00
const prefix = line . substring ( 0 , match . index ) ;
2021-10-21 13:13:42 +02:00
if ( ! linkDestinationRe . test ( prefix ) ) {
2022-06-02 21:42:48 -07:00
const unescaped = unescapeMarkdown ( prefix + "<" , "_" ) ;
2021-10-21 13:13:42 +02:00
if ( ! unescaped . endsWith ( "_" ) ) {
2022-08-02 20:36:47 -07:00
addError ( onError , lineIndex + 1 , "Element: " + element , undefined , [ match . index + 1 , tag . length ] ) ;
2019-10-02 20:10:42 -07:00
}
}
}
}
} ) ;
}
} ;
2021-01-05 20:55:09 -08:00
/***/ } ) ,
2021-01-06 19:45:15 -08:00
/***/ "../lib/md034.js" :
/ * ! * * * * * * * * * * * * * * * * * * * * * * * ! * \
! * * * . . / lib / md034 . js * * * !
\ * * * * * * * * * * * * * * * * * * * * * * * /
2021-01-05 20:55:09 -08:00
/***/ ( ( module , _ _unused _webpack _exports , _ _webpack _require _ _ ) => {
2019-10-02 20:10:42 -07:00
"use strict" ;
2021-01-05 20:55:09 -08:00
// @ts-check
2022-06-02 21:42:48 -07:00
const { addErrorContext , bareUrlRe , filterTokens } = _ _webpack _require _ _ ( /*! ../helpers */ "../helpers/helpers.js" ) ;
2019-10-02 20:10:42 -07:00
module . exports = {
"names" : [ "MD034" , "no-bare-urls" ] ,
"description" : "Bare URL used" ,
"tags" : [ "links" , "url" ] ,
"function" : function MD034 ( params , onError ) {
2022-06-02 21:42:48 -07:00
filterTokens ( params , "inline" , ( token ) => {
let inLink = false ;
2022-06-08 22:10:27 -07:00
for ( const child of token . children ) {
2022-06-02 21:42:48 -07:00
const { content , line , lineNumber , type } = child ;
let match = null ;
2019-10-02 20:10:42 -07:00
if ( type === "link_open" ) {
inLink = true ;
}
else if ( type === "link_close" ) {
inLink = false ;
}
else if ( ( type === "text" ) && ! inLink ) {
while ( ( match = bareUrlRe . exec ( content ) ) !== null ) {
2022-06-02 21:42:48 -07:00
const [ bareUrl ] = match ;
const matchIndex = match . index ;
const bareUrlLength = bareUrl . length ;
2020-04-11 13:54:46 -07:00
// Allow "[https://example.com]" to avoid conflicts with
// MD011/no-reversed-links; allow quoting as another way
// of deliberately including a bare URL
2022-06-02 21:42:48 -07:00
const leftChar = content [ matchIndex - 1 ] ;
const rightChar = content [ matchIndex + bareUrlLength ] ;
2020-04-11 13:54:46 -07:00
if ( ! ( ( leftChar === "[" ) && ( rightChar === "]" ) ) &&
! ( ( leftChar === "\"" ) && ( rightChar === "\"" ) ) &&
! ( ( leftChar === "'" ) && ( rightChar === "'" ) ) ) {
2022-06-02 21:42:48 -07:00
const index = line . indexOf ( content ) ;
const range = ( index === - 1 ) ? null : [
2020-04-11 13:54:46 -07:00
index + matchIndex + 1 ,
bareUrlLength
] ;
2022-06-02 21:42:48 -07:00
const fixInfo = range ? {
2020-04-11 13:54:46 -07:00
"editColumn" : range [ 0 ] ,
"deleteCount" : range [ 1 ] ,
2022-06-02 21:42:48 -07:00
"insertText" : ` < ${ bareUrl } > `
2020-04-11 13:54:46 -07:00
} : null ;
addErrorContext ( onError , lineNumber , bareUrl , null , null , range , fixInfo ) ;
}
2019-10-02 20:10:42 -07:00
}
}
2022-06-08 22:10:27 -07:00
}
2019-10-02 20:10:42 -07:00
} ) ;
}
} ;
2021-01-05 20:55:09 -08:00
/***/ } ) ,
2021-01-06 19:45:15 -08:00
/***/ "../lib/md035.js" :
/ * ! * * * * * * * * * * * * * * * * * * * * * * * ! * \
! * * * . . / lib / md035 . js * * * !
\ * * * * * * * * * * * * * * * * * * * * * * * /
2021-01-05 20:55:09 -08:00
/***/ ( ( module , _ _unused _webpack _exports , _ _webpack _require _ _ ) => {
2019-10-02 20:10:42 -07:00
"use strict" ;
2021-01-05 20:55:09 -08:00
// @ts-check
2022-06-02 21:42:48 -07:00
const { addErrorDetailIf , filterTokens } = _ _webpack _require _ _ ( /*! ../helpers */ "../helpers/helpers.js" ) ;
2019-10-02 20:10:42 -07:00
module . exports = {
"names" : [ "MD035" , "hr-style" ] ,
"description" : "Horizontal rule style" ,
"tags" : [ "hr" ] ,
"function" : function MD035 ( params , onError ) {
2022-06-02 21:42:48 -07:00
let style = String ( params . config . style || "consistent" ) . trim ( ) ;
filterTokens ( params , "hr" , ( token ) => {
const { line , lineNumber } = token ;
let { markup } = token ;
const match = line . match ( /[_*\-\s\t]+$/ ) ;
2022-04-28 21:53:51 -07:00
if ( match ) {
markup = match [ 0 ] . trim ( ) ;
}
2019-10-02 20:10:42 -07:00
if ( style === "consistent" ) {
2021-12-14 23:05:03 -08:00
style = markup ;
2019-10-02 20:10:42 -07:00
}
2021-12-14 23:05:03 -08:00
addErrorDetailIf ( onError , lineNumber , style , markup ) ;
2019-10-02 20:10:42 -07:00
} ) ;
}
} ;
2021-01-05 20:55:09 -08:00
/***/ } ) ,
2021-01-06 19:45:15 -08:00
/***/ "../lib/md036.js" :
/ * ! * * * * * * * * * * * * * * * * * * * * * * * ! * \
! * * * . . / lib / md036 . js * * * !
\ * * * * * * * * * * * * * * * * * * * * * * * /
2021-01-05 20:55:09 -08:00
/***/ ( ( module , _ _unused _webpack _exports , _ _webpack _require _ _ ) => {
2019-10-02 20:10:42 -07:00
"use strict" ;
2021-01-05 20:55:09 -08:00
// @ts-check
2022-06-02 21:42:48 -07:00
const { addErrorContext , allPunctuation } = _ _webpack _require _ _ ( /*! ../helpers */ "../helpers/helpers.js" ) ;
2019-10-02 20:10:42 -07:00
module . exports = {
"names" : [ "MD036" , "no-emphasis-as-heading" , "no-emphasis-as-header" ] ,
"description" : "Emphasis used instead of a heading" ,
"tags" : [ "headings" , "headers" , "emphasis" ] ,
"function" : function MD036 ( params , onError ) {
2022-06-02 21:42:48 -07:00
let punctuation = params . config . punctuation ;
2020-01-27 19:19:34 -08:00
punctuation =
String ( ( punctuation === undefined ) ? allPunctuation : punctuation ) ;
2022-06-02 21:42:48 -07:00
const re = new RegExp ( "[" + punctuation + "]$" ) ;
2020-01-27 19:19:34 -08:00
// eslint-disable-next-line jsdoc/require-jsdoc
2019-10-02 20:10:42 -07:00
function base ( token ) {
if ( token . type === "paragraph_open" ) {
return function inParagraph ( t ) {
// Always paragraph_open/inline/paragraph_close,
2022-06-02 21:42:48 -07:00
const children = t . children . filter ( function notEmptyText ( child ) {
2019-10-02 20:10:42 -07:00
return ( child . type !== "text" ) || ( child . content !== "" ) ;
} ) ;
if ( ( children . length === 3 ) &&
( ( children [ 0 ] . type === "strong_open" ) ||
( children [ 0 ] . type === "em_open" ) ) &&
( children [ 1 ] . type === "text" ) &&
! re . test ( children [ 1 ] . content ) ) {
addErrorContext ( onError , t . lineNumber , children [ 1 ] . content ) ;
}
return base ;
} ;
}
else if ( token . type === "blockquote_open" ) {
return function inBlockquote ( t ) {
if ( t . type !== "blockquote_close" ) {
return inBlockquote ;
}
return base ;
} ;
}
else if ( token . type === "list_item_open" ) {
return function inListItem ( t ) {
if ( t . type !== "list_item_close" ) {
return inListItem ;
}
return base ;
} ;
}
return base ;
}
2022-06-02 21:42:48 -07:00
let state = base ;
2022-06-08 22:10:27 -07:00
for ( const token of params . tokens ) {
2019-10-02 20:10:42 -07:00
state = state ( token ) ;
2022-06-08 22:10:27 -07:00
}
2019-10-02 20:10:42 -07:00
}
} ;
2021-01-05 20:55:09 -08:00
/***/ } ) ,
2021-01-06 19:45:15 -08:00
/***/ "../lib/md037.js" :
/ * ! * * * * * * * * * * * * * * * * * * * * * * * ! * \
! * * * . . / lib / md037 . js * * * !
\ * * * * * * * * * * * * * * * * * * * * * * * /
2021-01-05 20:55:09 -08:00
/***/ ( ( module , _ _unused _webpack _exports , _ _webpack _require _ _ ) => {
2019-10-02 20:10:42 -07:00
"use strict" ;
2021-01-05 20:55:09 -08:00
// @ts-check
2022-07-30 20:35:27 -07:00
const { addErrorContext , emphasisMarkersInContent , forEachLine , isBlankLine , withinAnyRange } = _ _webpack _require _ _ ( /*! ../helpers */ "../helpers/helpers.js" ) ;
const { htmlElementRanges , lineMetadata } = _ _webpack _require _ _ ( /*! ./cache */ "../lib/cache.js" ) ;
2022-06-02 21:42:48 -07:00
const emphasisRe = /(^|[^\\]|\\\\)(?:(\*\*?\*?)|(__?_?))/g ;
const embeddedUnderscoreRe = /([A-Za-z0-9])_([A-Za-z0-9])/g ;
const asteriskListItemMarkerRe = /^([\s>]*)\*(\s+)/ ;
const leftSpaceRe = /^\s+/ ;
const rightSpaceRe = /\s+$/ ;
const tablePipeRe = /\|/ ;
2019-10-02 20:10:42 -07:00
module . exports = {
"names" : [ "MD037" , "no-space-in-emphasis" ] ,
"description" : "Spaces inside emphasis markers" ,
"tags" : [ "whitespace" , "emphasis" ] ,
"function" : function MD037 ( params , onError ) {
2022-07-30 20:35:27 -07:00
const exclusions = htmlElementRanges ( ) ;
2020-04-12 20:48:04 -07:00
// eslint-disable-next-line init-declarations
2022-06-02 21:42:48 -07:00
let effectiveEmphasisLength , emphasisIndex , emphasisKind , emphasisLength , pendingError = null ;
2020-04-12 20:48:04 -07:00
// eslint-disable-next-line jsdoc/require-jsdoc
function resetRunTracking ( ) {
emphasisIndex = - 1 ;
emphasisLength = 0 ;
2020-04-25 21:15:13 -07:00
emphasisKind = "" ;
2020-04-12 20:48:04 -07:00
effectiveEmphasisLength = 0 ;
pendingError = null ;
}
// eslint-disable-next-line jsdoc/require-jsdoc
2021-01-23 20:47:27 -08:00
function handleRunEnd ( line , lineIndex , contextLength , match , matchIndex , inTable ) {
2020-04-12 20:48:04 -07:00
// Close current run
2022-06-02 21:42:48 -07:00
let content = line . substring ( emphasisIndex , matchIndex ) ;
2020-04-12 20:48:04 -07:00
if ( ! emphasisLength ) {
2021-02-06 19:55:22 -08:00
content = content . trimStart ( ) ;
2020-04-12 20:48:04 -07:00
}
if ( ! match ) {
2021-02-06 19:55:22 -08:00
content = content . trimEnd ( ) ;
2020-04-12 20:48:04 -07:00
}
2022-06-02 21:42:48 -07:00
const leftSpace = leftSpaceRe . test ( content ) ;
const rightSpace = rightSpaceRe . test ( content ) ;
2021-01-23 20:47:27 -08:00
if ( ( leftSpace || rightSpace ) &&
( ! inTable || ! tablePipeRe . test ( content ) ) ) {
2020-04-12 20:48:04 -07:00
// Report the violation
2022-06-02 21:42:48 -07:00
const contextStart = emphasisIndex - emphasisLength ;
const contextEnd = matchIndex + contextLength ;
const column = contextStart + 1 ;
const length = contextEnd - contextStart ;
2022-07-30 20:35:27 -07:00
if ( ! withinAnyRange ( exclusions , lineIndex , column , length ) ) {
const context = line . substring ( contextStart , contextEnd ) ;
const leftMarker = line . substring ( contextStart , emphasisIndex ) ;
const rightMarker = match ? ( match [ 2 ] || match [ 3 ] ) : "" ;
const fixedText = ` ${ leftMarker } ${ content . trim ( ) } ${ rightMarker } ` ;
return [
onError ,
lineIndex + 1 ,
context ,
leftSpace ,
rightSpace ,
[ column , length ] ,
{
"editColumn" : column ,
"deleteCount" : length ,
"insertText" : fixedText
}
] ;
}
2020-04-12 20:48:04 -07:00
}
return null ;
}
// Initialize
2022-06-02 21:42:48 -07:00
const ignoreMarkersByLine = emphasisMarkersInContent ( params ) ;
2020-04-12 20:48:04 -07:00
resetRunTracking ( ) ;
2022-06-02 21:42:48 -07:00
forEachLine ( lineMetadata ( ) , ( line , lineIndex , inCode , onFence , inTable , inItem , onBreak , inMath ) => {
const onItemStart = ( inItem === 1 ) ;
2021-08-22 15:28:28 -07:00
if ( inCode ||
onFence ||
inTable ||
onBreak ||
onItemStart ||
isBlankLine ( line ) ) {
2020-04-12 20:48:04 -07:00
// Emphasis resets when leaving a block
resetRunTracking ( ) ;
}
2021-08-22 15:28:28 -07:00
if ( inCode ||
onFence ||
onBreak ||
inMath ) {
2020-04-11 13:54:46 -07:00
// Emphasis has no meaning here
return ;
}
2022-06-02 21:42:48 -07:00
let patchedLine = line . replace ( embeddedUnderscoreRe , "$1 $2" ) ;
2020-04-12 20:48:04 -07:00
if ( onItemStart ) {
2020-04-11 13:54:46 -07:00
// Trim overlapping '*' list item marker
2021-12-21 22:21:28 +00:00
patchedLine = patchedLine . replace ( asteriskListItemMarkerRe , "$1 $2" ) ;
2020-04-11 13:54:46 -07:00
}
2022-06-02 21:42:48 -07:00
let match = null ;
2020-04-11 13:54:46 -07:00
// Match all emphasis-looking runs in the line...
2021-12-21 22:21:28 +00:00
while ( ( match = emphasisRe . exec ( patchedLine ) ) ) {
2022-06-02 21:42:48 -07:00
const ignoreMarkersForLine = ignoreMarkersByLine [ lineIndex ] ;
const matchIndex = match . index + match [ 1 ] . length ;
2020-05-14 21:49:05 -07:00
if ( ignoreMarkersForLine . includes ( matchIndex ) ) {
// Ignore emphasis markers inside code spans and links
2020-04-25 21:15:13 -07:00
continue ;
}
2022-06-02 21:42:48 -07:00
const matchLength = match [ 0 ] . length - match [ 1 ] . length ;
const matchKind = ( match [ 2 ] || match [ 3 ] ) [ 0 ] ;
2020-04-11 13:54:46 -07:00
if ( emphasisIndex === - 1 ) {
// New run
emphasisIndex = matchIndex + matchLength ;
emphasisLength = matchLength ;
2020-04-25 21:15:13 -07:00
emphasisKind = matchKind ;
2020-04-11 13:54:46 -07:00
effectiveEmphasisLength = matchLength ;
}
2020-05-14 21:49:05 -07:00
else if ( matchKind === emphasisKind ) {
// Matching emphasis markers
if ( matchLength === effectiveEmphasisLength ) {
// Ending an existing run, report any pending error
if ( pendingError ) {
2021-01-06 20:20:18 -08:00
// @ts-ignore
2022-06-02 21:42:48 -07:00
addErrorContext ( ... pendingError ) ;
2020-05-14 21:49:05 -07:00
pendingError = null ;
}
2022-06-02 21:42:48 -07:00
const error = handleRunEnd ( line , lineIndex , effectiveEmphasisLength , match , matchIndex , inTable ) ;
2020-05-14 21:49:05 -07:00
if ( error ) {
2021-01-06 20:20:18 -08:00
// @ts-ignore
2022-06-02 21:42:48 -07:00
addErrorContext ( ... error ) ;
2020-05-14 21:49:05 -07:00
}
// Reset
resetRunTracking ( ) ;
2020-04-12 20:48:04 -07:00
}
2020-05-14 21:49:05 -07:00
else if ( matchLength === 3 ) {
// Swap internal run length (1->2 or 2->1)
effectiveEmphasisLength = matchLength - effectiveEmphasisLength ;
2019-10-02 20:10:42 -07:00
}
2020-05-14 21:49:05 -07:00
else if ( effectiveEmphasisLength === 3 ) {
// Downgrade internal run (3->1 or 3->2)
effectiveEmphasisLength -= matchLength ;
}
else {
// Upgrade to internal run (1->3 or 2->3)
effectiveEmphasisLength += matchLength ;
}
// Back up one character so RegExp has a chance to match the
// next marker (ex: "**star**_underscore_")
2020-06-23 20:14:58 -07:00
if ( emphasisRe . lastIndex > 1 ) {
emphasisRe . lastIndex -- ;
}
2020-04-11 13:54:46 -07:00
}
2020-05-14 21:49:05 -07:00
else if ( emphasisRe . lastIndex > 1 ) {
// Back up one character so RegExp has a chance to match the
// mis-matched marker (ex: "*text_*")
emphasisRe . lastIndex -- ;
2020-04-11 13:54:46 -07:00
}
}
2020-04-12 20:48:04 -07:00
if ( emphasisIndex !== - 1 ) {
pendingError = pendingError ||
2021-01-23 20:47:27 -08:00
handleRunEnd ( line , lineIndex , 0 , null , line . length , inTable ) ;
2020-04-12 20:48:04 -07:00
// Adjust for pending run on new line
emphasisIndex = 0 ;
emphasisLength = 0 ;
}
2019-10-02 20:10:42 -07:00
} ) ;
}
} ;
2021-01-05 20:55:09 -08:00
/***/ } ) ,
2021-01-06 19:45:15 -08:00
/***/ "../lib/md038.js" :
/ * ! * * * * * * * * * * * * * * * * * * * * * * * ! * \
! * * * . . / lib / md038 . js * * * !
\ * * * * * * * * * * * * * * * * * * * * * * * /
2021-01-05 20:55:09 -08:00
/***/ ( ( module , _ _unused _webpack _exports , _ _webpack _require _ _ ) => {
2019-10-02 20:10:42 -07:00
"use strict" ;
2021-01-05 20:55:09 -08:00
// @ts-check
2022-06-02 21:42:48 -07:00
const { addErrorContext , filterTokens , forEachInlineCodeSpan , newLineRe } = _ _webpack _require _ _ ( /*! ../helpers */ "../helpers/helpers.js" ) ;
const leftSpaceRe = /^\s([^`]|$)/ ;
const rightSpaceRe = /[^`]\s$/ ;
2022-06-12 19:04:39 -07:00
const spaceInsideCodeInline = ( token ) => ( ( token . type === "code_inline" ) &&
( leftSpaceRe . test ( token . content ) || rightSpaceRe . test ( token . content ) ) ) ;
2019-10-02 20:10:42 -07:00
module . exports = {
"names" : [ "MD038" , "no-space-in-code" ] ,
"description" : "Spaces inside code span elements" ,
"tags" : [ "whitespace" , "code" ] ,
"function" : function MD038 ( params , onError ) {
2022-06-02 21:42:48 -07:00
filterTokens ( params , "inline" , ( token ) => {
2022-06-12 19:04:39 -07:00
if ( token . children . some ( spaceInsideCodeInline ) ) {
2022-06-02 21:42:48 -07:00
const tokenLines = params . lines . slice ( token . map [ 0 ] , token . map [ 1 ] ) ;
forEachInlineCodeSpan ( tokenLines . join ( "\n" ) , ( code , lineIndex , columnIndex , tickCount ) => {
let rangeIndex = columnIndex - tickCount ;
let rangeLength = code . length + ( 2 * tickCount ) ;
let rangeLineOffset = 0 ;
let fixIndex = columnIndex ;
let fixLength = code . length ;
const codeLines = code . split ( newLineRe ) ;
const left = leftSpaceRe . test ( code ) ;
const right = ! left && rightSpaceRe . test ( code ) ;
2019-10-02 20:10:42 -07:00
if ( right && ( codeLines . length > 1 ) ) {
rangeIndex = 0 ;
rangeLineOffset = codeLines . length - 1 ;
fixIndex = 0 ;
}
2022-06-12 19:04:39 -07:00
if ( left || right ) {
2022-06-02 21:42:48 -07:00
const codeLinesRange = codeLines [ rangeLineOffset ] ;
2019-10-02 20:10:42 -07:00
if ( codeLines . length > 1 ) {
rangeLength = codeLinesRange . length + tickCount ;
fixLength = codeLinesRange . length ;
}
2022-06-02 21:42:48 -07:00
const context = tokenLines [ lineIndex + rangeLineOffset ]
2019-10-02 20:10:42 -07:00
. substring ( rangeIndex , rangeIndex + rangeLength ) ;
2022-06-02 21:42:48 -07:00
const codeLinesRangeTrim = codeLinesRange . trim ( ) ;
const fixText = ( codeLinesRangeTrim . startsWith ( "`" ) ? " " : "" ) +
2019-10-02 20:10:42 -07:00
codeLinesRangeTrim +
( codeLinesRangeTrim . endsWith ( "`" ) ? " " : "" ) ;
addErrorContext ( onError , token . lineNumber + lineIndex + rangeLineOffset , context , left , right , [ rangeIndex + 1 , rangeLength ] , {
"editColumn" : fixIndex + 1 ,
"deleteCount" : fixLength ,
"insertText" : fixText
} ) ;
}
} ) ;
}
} ) ;
}
} ;
2021-01-05 20:55:09 -08:00
/***/ } ) ,
2021-01-06 19:45:15 -08:00
/***/ "../lib/md039.js" :
/ * ! * * * * * * * * * * * * * * * * * * * * * * * ! * \
! * * * . . / lib / md039 . js * * * !
\ * * * * * * * * * * * * * * * * * * * * * * * /
2021-01-05 20:55:09 -08:00
/***/ ( ( module , _ _unused _webpack _exports , _ _webpack _require _ _ ) => {
2019-10-02 20:10:42 -07:00
"use strict" ;
2021-01-05 20:55:09 -08:00
// @ts-check
2022-06-02 21:42:48 -07:00
const { addErrorContext , filterTokens } = _ _webpack _require _ _ ( /*! ../helpers */ "../helpers/helpers.js" ) ;
const spaceInLinkRe = /\[(?:\s+(?:[^\]]*?)\s*|(?:[^\]]*?)\s+)](?=((?:\([^)]*\))|(?:\[[^\]]*\])))/ ;
2019-10-02 20:10:42 -07:00
module . exports = {
"names" : [ "MD039" , "no-space-in-links" ] ,
"description" : "Spaces inside link text" ,
"tags" : [ "whitespace" , "links" ] ,
"function" : function MD039 ( params , onError ) {
2022-06-02 21:42:48 -07:00
filterTokens ( params , "inline" , ( token ) => {
const { children } = token ;
let { lineNumber } = token ;
let inLink = false ;
let linkText = "" ;
let lineIndex = 0 ;
2022-06-08 22:10:27 -07:00
for ( const child of children ) {
2022-06-02 21:42:48 -07:00
const { content , markup , type } = child ;
2019-10-02 20:10:42 -07:00
if ( type === "link_open" ) {
inLink = true ;
linkText = "" ;
}
else if ( type === "link_close" ) {
inLink = false ;
2022-06-02 21:42:48 -07:00
const left = linkText . trimStart ( ) . length !== linkText . length ;
const right = linkText . trimEnd ( ) . length !== linkText . length ;
2019-10-02 20:10:42 -07:00
if ( left || right ) {
2022-06-02 21:42:48 -07:00
const line = params . lines [ lineNumber - 1 ] ;
let range = null ;
let fixInfo = null ;
const match = line . slice ( lineIndex ) . match ( spaceInLinkRe ) ;
2020-04-11 13:54:46 -07:00
if ( match ) {
2022-06-02 21:42:48 -07:00
const column = match . index + lineIndex + 1 ;
const length = match [ 0 ] . length ;
2021-11-13 12:40:51 -08:00
range = [ column , length ] ;
2020-04-11 13:54:46 -07:00
fixInfo = {
"editColumn" : column + 1 ,
2021-11-13 12:40:51 -08:00
"deleteCount" : length - 2 ,
2020-04-11 13:54:46 -07:00
"insertText" : linkText . trim ( )
} ;
2021-11-13 12:40:51 -08:00
lineIndex = column + length - 1 ;
2020-04-11 13:54:46 -07:00
}
2022-06-02 21:42:48 -07:00
addErrorContext ( onError , lineNumber , ` [ ${ linkText } ] ` , left , right , range , fixInfo ) ;
2019-10-02 20:10:42 -07:00
}
}
else if ( ( type === "softbreak" ) || ( type === "hardbreak" ) ) {
lineNumber ++ ;
lineIndex = 0 ;
}
else if ( inLink ) {
2022-05-06 21:42:31 -07:00
linkText += type . endsWith ( "_inline" ) ?
2022-06-02 21:42:48 -07:00
` ${ markup } ${ content } ${ markup } ` :
2022-05-06 21:42:31 -07:00
( content || markup ) ;
2019-10-02 20:10:42 -07:00
}
2022-06-08 22:10:27 -07:00
}
2019-10-02 20:10:42 -07:00
} ) ;
}
} ;
2021-01-05 20:55:09 -08:00
/***/ } ) ,
2021-01-06 19:45:15 -08:00
/***/ "../lib/md040.js" :
/ * ! * * * * * * * * * * * * * * * * * * * * * * * ! * \
! * * * . . / lib / md040 . js * * * !
\ * * * * * * * * * * * * * * * * * * * * * * * /
2021-01-05 20:55:09 -08:00
/***/ ( ( module , _ _unused _webpack _exports , _ _webpack _require _ _ ) => {
2019-10-02 20:10:42 -07:00
"use strict" ;
2021-01-05 20:55:09 -08:00
// @ts-check
2022-10-18 03:29:29 +08:00
const { addError , addErrorContext , filterTokens } = _ _webpack _require _ _ ( /*! ../helpers */ "../helpers/helpers.js" ) ;
2019-10-02 20:10:42 -07:00
module . exports = {
"names" : [ "MD040" , "fenced-code-language" ] ,
"description" : "Fenced code blocks should have a language specified" ,
"tags" : [ "code" , "language" ] ,
"function" : function MD040 ( params , onError ) {
2022-10-18 03:29:29 +08:00
let allowed = params . config . allowed _languages ;
allowed = Array . isArray ( allowed ) ?
allowed . map ( ( lang ) => lang . toLowerCase ( ) ) :
[ ] ;
2019-10-02 20:10:42 -07:00
filterTokens ( params , "fence" , function forToken ( token ) {
2022-10-18 03:29:29 +08:00
const lang = token . info . trim ( ) ;
if ( lang === "" ) {
2019-10-02 20:10:42 -07:00
addErrorContext ( onError , token . lineNumber , token . line ) ;
}
2022-10-18 03:29:29 +08:00
else if ( allowed . length > 0 &&
! allowed . includes ( lang . toLowerCase ( ) ) ) {
addError ( onError , token . lineNumber , ` " ${ lang } " is not allowed ` ) ;
}
2019-10-02 20:10:42 -07:00
} ) ;
}
} ;
2021-01-05 20:55:09 -08:00
/***/ } ) ,
2021-01-06 19:45:15 -08:00
/***/ "../lib/md041.js" :
/ * ! * * * * * * * * * * * * * * * * * * * * * * * ! * \
! * * * . . / lib / md041 . js * * * !
\ * * * * * * * * * * * * * * * * * * * * * * * /
2021-01-05 20:55:09 -08:00
/***/ ( ( module , _ _unused _webpack _exports , _ _webpack _require _ _ ) => {
2019-10-02 20:10:42 -07:00
"use strict" ;
2021-01-05 20:55:09 -08:00
// @ts-check
2022-06-02 21:42:48 -07:00
const { addErrorContext , frontMatterHasTitle } = _ _webpack _require _ _ ( /*! ../helpers */ "../helpers/helpers.js" ) ;
2019-10-02 20:10:42 -07:00
module . exports = {
"names" : [ "MD041" , "first-line-heading" , "first-line-h1" ] ,
2020-12-28 13:28:38 -08:00
"description" : "First line in a file should be a top-level heading" ,
2019-10-02 20:10:42 -07:00
"tags" : [ "headings" , "headers" ] ,
"function" : function MD041 ( params , onError ) {
2022-06-02 21:42:48 -07:00
const level = Number ( params . config . level || 1 ) ;
const tag = "h" + level ;
const foundFrontMatterTitle = frontMatterHasTitle ( params . frontMatterLines , params . config . front _matter _title ) ;
2019-10-02 20:10:42 -07:00
if ( ! foundFrontMatterTitle ) {
2022-06-02 21:42:48 -07:00
const htmlHeadingRe = new RegExp ( ` ^<h ${ level } [ />] ` , "i" ) ;
params . tokens . every ( ( token ) => {
let isError = false ;
2019-10-02 20:10:42 -07:00
if ( token . type === "html_block" ) {
2021-01-31 15:48:00 -08:00
if ( token . content . startsWith ( "<!--" ) ) {
// Ignore leading HTML comments
return true ;
}
2022-06-02 21:42:48 -07:00
else if ( ! htmlHeadingRe . test ( token . content ) ) {
2021-01-31 15:48:00 -08:00
// Something other than an HTML heading
isError = true ;
}
}
else if ( ( token . type !== "heading_open" ) || ( token . tag !== tag ) ) {
// Something other than a Markdown heading
isError = true ;
2019-10-02 20:10:42 -07:00
}
2021-01-31 15:48:00 -08:00
if ( isError ) {
2019-10-02 20:10:42 -07:00
addErrorContext ( onError , token . lineNumber , token . line ) ;
}
return false ;
} ) ;
}
}
} ;
2021-01-05 20:55:09 -08:00
/***/ } ) ,
2021-01-06 19:45:15 -08:00
/***/ "../lib/md042.js" :
/ * ! * * * * * * * * * * * * * * * * * * * * * * * ! * \
! * * * . . / lib / md042 . js * * * !
\ * * * * * * * * * * * * * * * * * * * * * * * /
2021-01-05 20:55:09 -08:00
/***/ ( ( module , _ _unused _webpack _exports , _ _webpack _require _ _ ) => {
2019-10-02 20:10:42 -07:00
"use strict" ;
2021-01-05 20:55:09 -08:00
// @ts-check
2022-06-02 21:42:48 -07:00
const { addErrorContext , escapeForRegExp , filterTokens } = _ _webpack _require _ _ ( /*! ../helpers */ "../helpers/helpers.js" ) ;
2019-10-02 20:10:42 -07:00
module . exports = {
"names" : [ "MD042" , "no-empty-links" ] ,
"description" : "No empty links" ,
"tags" : [ "links" ] ,
"function" : function MD042 ( params , onError ) {
filterTokens ( params , "inline" , function forToken ( token ) {
2022-06-02 21:42:48 -07:00
let inLink = false ;
let linkText = "" ;
let emptyLink = false ;
2022-06-08 22:10:27 -07:00
for ( const child of token . children ) {
2019-10-02 20:10:42 -07:00
if ( child . type === "link_open" ) {
inLink = true ;
linkText = "" ;
2022-06-08 22:10:27 -07:00
for ( const attr of child . attrs ) {
2019-10-02 20:10:42 -07:00
if ( attr [ 0 ] === "href" && ( ! attr [ 1 ] || ( attr [ 1 ] === "#" ) ) ) {
emptyLink = true ;
}
2022-06-08 22:10:27 -07:00
}
2019-10-02 20:10:42 -07:00
}
else if ( child . type === "link_close" ) {
inLink = false ;
if ( emptyLink ) {
2022-06-02 21:42:48 -07:00
let context = ` [ ${ linkText } ] ` ;
let range = null ;
const match = child . line . match ( new RegExp ( ` ${ escapeForRegExp ( context ) } \\ ((?:|#|<>) \\ ) ` ) ) ;
2022-02-13 17:41:31 -08:00
if ( match ) {
context = match [ 0 ] ;
range = [ match . index + 1 , match [ 0 ] . length ] ;
}
addErrorContext ( onError , child . lineNumber , context , null , null , range ) ;
2020-09-13 21:15:11 -07:00
emptyLink = false ;
2019-10-02 20:10:42 -07:00
}
}
else if ( inLink ) {
linkText += child . content ;
}
2022-06-08 22:10:27 -07:00
}
2019-10-02 20:10:42 -07:00
} ) ;
}
} ;
2021-01-05 20:55:09 -08:00
/***/ } ) ,
2021-01-06 19:45:15 -08:00
/***/ "../lib/md043.js" :
/ * ! * * * * * * * * * * * * * * * * * * * * * * * ! * \
! * * * . . / lib / md043 . js * * * !
\ * * * * * * * * * * * * * * * * * * * * * * * /
2021-01-05 20:55:09 -08:00
/***/ ( ( module , _ _unused _webpack _exports , _ _webpack _require _ _ ) => {
2019-10-02 20:10:42 -07:00
"use strict" ;
2021-01-05 20:55:09 -08:00
// @ts-check
2022-06-02 21:42:48 -07:00
const { addErrorContext , addErrorDetailIf , forEachHeading } = _ _webpack _require _ _ ( /*! ../helpers */ "../helpers/helpers.js" ) ;
2019-10-02 20:10:42 -07:00
module . exports = {
"names" : [ "MD043" , "required-headings" , "required-headers" ] ,
"description" : "Required heading structure" ,
"tags" : [ "headings" , "headers" ] ,
"function" : function MD043 ( params , onError ) {
2022-06-02 21:42:48 -07:00
const requiredHeadings = params . config . headings || params . config . headers ;
2022-10-22 03:15:50 -04:00
const matchCase = params . config . match _case || false ;
2020-01-27 19:19:34 -08:00
if ( Array . isArray ( requiredHeadings ) ) {
2022-06-02 21:42:48 -07:00
const levels = { } ;
2022-06-08 22:10:27 -07:00
for ( const level of [ 1 , 2 , 3 , 4 , 5 , 6 ] ) {
2022-06-02 21:42:48 -07:00
levels [ "h" + level ] = "######" . substr ( - level ) ;
2022-06-08 22:10:27 -07:00
}
2022-06-02 21:42:48 -07:00
let i = 0 ;
let matchAny = false ;
let hasError = false ;
let anyHeadings = false ;
const getExpected = ( ) => requiredHeadings [ i ++ ] || "[None]" ;
2022-10-22 03:15:50 -04:00
const handleCase = ( str ) => ( matchCase ? str : str . toLowerCase ( ) ) ;
2022-06-02 21:42:48 -07:00
forEachHeading ( params , ( heading , content ) => {
if ( ! hasError ) {
anyHeadings = true ;
const actual = levels [ heading . tag ] + " " + content ;
const expected = getExpected ( ) ;
2019-10-02 20:10:42 -07:00
if ( expected === "*" ) {
2022-06-02 21:42:48 -07:00
const nextExpected = getExpected ( ) ;
2022-10-22 03:15:50 -04:00
if ( handleCase ( nextExpected ) !== handleCase ( actual ) ) {
2022-06-02 21:42:48 -07:00
matchAny = true ;
i -- ;
2021-05-20 15:45:27 -04:00
}
2020-11-24 16:37:11 -08:00
}
else if ( expected === "+" ) {
2022-06-02 21:42:48 -07:00
matchAny = true ;
2019-10-02 20:10:42 -07:00
}
2022-10-22 03:15:50 -04:00
else if ( handleCase ( expected ) === handleCase ( actual ) ) {
2022-06-02 21:42:48 -07:00
matchAny = false ;
2019-10-02 20:10:42 -07:00
}
2022-06-02 21:42:48 -07:00
else if ( matchAny ) {
i -- ;
2019-10-02 20:10:42 -07:00
}
else {
addErrorDetailIf ( onError , heading . lineNumber , expected , actual ) ;
2022-06-02 21:42:48 -07:00
hasError = true ;
2019-10-02 20:10:42 -07:00
}
}
} ) ;
2022-06-02 21:42:48 -07:00
const extraHeadings = requiredHeadings . length - i ;
if ( ! hasError &&
2021-05-20 15:45:27 -04:00
( ( extraHeadings > 1 ) ||
2022-06-02 21:42:48 -07:00
( ( extraHeadings === 1 ) && ( requiredHeadings [ i ] !== "*" ) ) ) &&
( anyHeadings || ! requiredHeadings . every ( ( heading ) => heading === "*" ) ) ) {
addErrorContext ( onError , params . lines . length , requiredHeadings [ i ] ) ;
2019-10-02 20:10:42 -07:00
}
}
}
} ;
2021-01-05 20:55:09 -08:00
/***/ } ) ,
2021-01-06 19:45:15 -08:00
/***/ "../lib/md044.js" :
/ * ! * * * * * * * * * * * * * * * * * * * * * * * ! * \
! * * * . . / lib / md044 . js * * * !
\ * * * * * * * * * * * * * * * * * * * * * * * /
2021-01-05 20:55:09 -08:00
/***/ ( ( module , _ _unused _webpack _exports , _ _webpack _require _ _ ) => {
"use strict" ;
// @ts-check
2022-06-02 22:17:32 -07:00
const { addErrorDetailIf , bareUrlRe , escapeForRegExp , forEachLine , forEachLink , withinAnyRange , linkReferenceDefinitionRe } = _ _webpack _require _ _ ( /*! ../helpers */ "../helpers/helpers.js" ) ;
2022-06-02 21:42:48 -07:00
const { codeBlockAndSpanRanges , htmlElementRanges , lineMetadata } = _ _webpack _require _ _ ( /*! ./cache */ "../lib/cache.js" ) ;
2019-10-02 20:10:42 -07:00
module . exports = {
"names" : [ "MD044" , "proper-names" ] ,
"description" : "Proper names should have the correct capitalization" ,
"tags" : [ "spelling" ] ,
"function" : function MD044 ( params , onError ) {
2022-06-02 21:42:48 -07:00
let names = params . config . names ;
2020-01-27 19:19:34 -08:00
names = Array . isArray ( names ) ? names : [ ] ;
2022-06-02 21:42:48 -07:00
names . sort ( ( a , b ) => ( b . length - a . length ) || a . localeCompare ( b ) ) ;
const codeBlocks = params . config . code _blocks ;
const includeCodeBlocks = ( codeBlocks === undefined ) ? true : ! ! codeBlocks ;
const htmlElements = params . config . html _elements ;
const includeHtmlElements = ( htmlElements === undefined ) ? true : ! ! htmlElements ;
const exclusions = [ ] ;
forEachLine ( lineMetadata ( ) , ( line , lineIndex ) => {
2022-06-01 20:23:08 -07:00
if ( linkReferenceDefinitionRe . test ( line ) ) {
2021-06-13 13:07:03 -07:00
exclusions . push ( [ lineIndex , 0 , line . length ] ) ;
}
else {
2022-06-02 21:42:48 -07:00
let match = null ;
2021-06-13 13:07:03 -07:00
while ( ( match = bareUrlRe . exec ( line ) ) !== null ) {
exclusions . push ( [ lineIndex , match . index , match [ 0 ] . length ] ) ;
}
2022-06-02 21:42:48 -07:00
forEachLink ( line , ( index , _ , text , destination ) => {
2021-06-13 13:07:03 -07:00
if ( destination ) {
2022-02-18 21:14:14 -08:00
exclusions . push ( [ lineIndex , index + text . length , destination . length ] ) ;
2021-06-13 13:07:03 -07:00
}
2022-02-18 21:14:14 -08:00
} ) ;
2021-06-13 13:07:03 -07:00
}
} ) ;
2021-06-12 17:10:59 -07:00
if ( ! includeCodeBlocks ) {
2022-06-02 21:42:48 -07:00
exclusions . push ( ... codeBlockAndSpanRanges ( ) ) ;
2021-06-12 17:10:59 -07:00
}
2022-04-25 21:50:33 -07:00
if ( ! includeHtmlElements ) {
2022-06-02 21:42:48 -07:00
exclusions . push ( ... htmlElementRanges ( ) ) ;
2022-04-25 21:50:33 -07:00
}
2022-06-02 21:42:48 -07:00
for ( const name of names ) {
const escapedName = escapeForRegExp ( name ) ;
const startNamePattern = /^\W/ . test ( name ) ? "" : "\\b_*" ;
const endNamePattern = /\W$/ . test ( name ) ? "" : "_*\\b" ;
const namePattern = ` ( ${ startNamePattern } )( ${ escapedName } ) ${ endNamePattern } ` ;
const nameRe = new RegExp ( namePattern , "gi" ) ;
forEachLine ( lineMetadata ( ) , ( line , lineIndex , inCode , onFence ) => {
2021-06-12 17:10:59 -07:00
if ( includeCodeBlocks || ( ! inCode && ! onFence ) ) {
2022-06-02 21:42:48 -07:00
let match = null ;
2021-06-17 21:50:03 -07:00
while ( ( match = nameRe . exec ( line ) ) !== null ) {
2022-06-02 21:42:48 -07:00
const [ , leftMatch , nameMatch ] = match ;
const index = match . index + leftMatch . length ;
const length = nameMatch . length ;
2022-06-02 22:17:32 -07:00
if ( ! withinAnyRange ( exclusions , lineIndex , index , length ) &&
2022-04-22 20:41:42 -07:00
! names . includes ( nameMatch ) ) {
2021-11-13 12:40:51 -08:00
addErrorDetailIf ( onError , lineIndex + 1 , name , nameMatch , null , null , [ index + 1 , length ] , {
2021-06-12 17:10:59 -07:00
"editColumn" : index + 1 ,
2021-11-13 12:40:51 -08:00
"deleteCount" : length ,
"insertText" : name
2021-06-12 17:10:59 -07:00
} ) ;
2019-10-02 20:10:42 -07:00
}
2021-11-13 12:40:51 -08:00
exclusions . push ( [ lineIndex , index , length ] ) ;
2021-06-12 17:10:59 -07:00
}
2020-09-20 12:22:27 -07:00
}
2021-06-12 17:10:59 -07:00
} ) ;
}
2019-10-02 20:10:42 -07:00
}
} ;
2021-01-05 20:55:09 -08:00
/***/ } ) ,
2021-01-06 19:45:15 -08:00
/***/ "../lib/md045.js" :
/ * ! * * * * * * * * * * * * * * * * * * * * * * * ! * \
! * * * . . / lib / md045 . js * * * !
\ * * * * * * * * * * * * * * * * * * * * * * * /
2021-01-05 20:55:09 -08:00
/***/ ( ( module , _ _unused _webpack _exports , _ _webpack _require _ _ ) => {
2019-10-02 20:10:42 -07:00
"use strict" ;
2021-01-05 20:55:09 -08:00
// @ts-check
2022-06-02 21:42:48 -07:00
const { addError , forEachInlineChild } = _ _webpack _require _ _ ( /*! ../helpers */ "../helpers/helpers.js" ) ;
2019-10-02 20:10:42 -07:00
module . exports = {
"names" : [ "MD045" , "no-alt-text" ] ,
"description" : "Images should have alternate text (alt text)" ,
"tags" : [ "accessibility" , "images" ] ,
"function" : function MD045 ( params , onError ) {
forEachInlineChild ( params , "image" , function forToken ( token ) {
if ( token . content === "" ) {
addError ( onError , token . lineNumber ) ;
}
} ) ;
}
} ;
2021-01-05 20:55:09 -08:00
/***/ } ) ,
2021-01-06 19:45:15 -08:00
/***/ "../lib/md046.js" :
/ * ! * * * * * * * * * * * * * * * * * * * * * * * ! * \
! * * * . . / lib / md046 . js * * * !
\ * * * * * * * * * * * * * * * * * * * * * * * /
2021-01-05 20:55:09 -08:00
/***/ ( ( module , _ _unused _webpack _exports , _ _webpack _require _ _ ) => {
2019-10-02 20:10:42 -07:00
"use strict" ;
2021-01-05 20:55:09 -08:00
// @ts-check
2022-06-02 21:42:48 -07:00
const { addErrorDetailIf } = _ _webpack _require _ _ ( /*! ../helpers */ "../helpers/helpers.js" ) ;
const tokenTypeToStyle = {
2019-10-02 20:10:42 -07:00
"fence" : "fenced" ,
"code_block" : "indented"
} ;
module . exports = {
"names" : [ "MD046" , "code-block-style" ] ,
"description" : "Code block style" ,
"tags" : [ "code" ] ,
"function" : function MD046 ( params , onError ) {
2022-06-02 21:42:48 -07:00
let expectedStyle = String ( params . config . style || "consistent" ) ;
2022-06-08 22:10:27 -07:00
const codeBlocksAndFences = params . tokens . filter ( ( token ) => ( token . type === "code_block" ) || ( token . type === "fence" ) ) ;
for ( const token of codeBlocksAndFences ) {
2022-06-02 21:42:48 -07:00
const { lineNumber , type } = token ;
2019-10-02 20:10:42 -07:00
if ( expectedStyle === "consistent" ) {
expectedStyle = tokenTypeToStyle [ type ] ;
}
addErrorDetailIf ( onError , lineNumber , expectedStyle , tokenTypeToStyle [ type ] ) ;
2022-06-08 22:10:27 -07:00
}
2019-10-02 20:10:42 -07:00
}
} ;
2021-01-05 20:55:09 -08:00
/***/ } ) ,
2021-01-06 19:45:15 -08:00
/***/ "../lib/md047.js" :
/ * ! * * * * * * * * * * * * * * * * * * * * * * * ! * \
! * * * . . / lib / md047 . js * * * !
\ * * * * * * * * * * * * * * * * * * * * * * * /
2021-01-05 20:55:09 -08:00
/***/ ( ( module , _ _unused _webpack _exports , _ _webpack _require _ _ ) => {
2019-10-02 20:10:42 -07:00
"use strict" ;
2021-01-05 20:55:09 -08:00
// @ts-check
2022-06-02 21:42:48 -07:00
const { addError , isBlankLine } = _ _webpack _require _ _ ( /*! ../helpers */ "../helpers/helpers.js" ) ;
2019-10-02 20:10:42 -07:00
module . exports = {
"names" : [ "MD047" , "single-trailing-newline" ] ,
"description" : "Files should end with a single newline character" ,
"tags" : [ "blank_lines" ] ,
"function" : function MD047 ( params , onError ) {
2022-06-02 21:42:48 -07:00
const lastLineNumber = params . lines . length ;
const lastLine = params . lines [ lastLineNumber - 1 ] ;
2019-10-02 20:10:42 -07:00
if ( ! isBlankLine ( lastLine ) ) {
addError ( onError , lastLineNumber , null , null , [ lastLine . length , 1 ] , {
"insertText" : "\n" ,
"editColumn" : lastLine . length + 1
} ) ;
}
}
} ;
2021-01-05 20:55:09 -08:00
/***/ } ) ,
2021-01-06 19:45:15 -08:00
/***/ "../lib/md048.js" :
/ * ! * * * * * * * * * * * * * * * * * * * * * * * ! * \
! * * * . . / lib / md048 . js * * * !
\ * * * * * * * * * * * * * * * * * * * * * * * /
2021-01-05 20:55:09 -08:00
/***/ ( ( module , _ _unused _webpack _exports , _ _webpack _require _ _ ) => {
2019-10-02 20:10:42 -07:00
"use strict" ;
2021-01-05 20:55:09 -08:00
// @ts-check
2022-06-02 21:42:48 -07:00
const { addErrorDetailIf , fencedCodeBlockStyleFor } = _ _webpack _require _ _ ( /*! ../helpers */ "../helpers/helpers.js" ) ;
2019-12-14 13:50:48 -08:00
module . exports = {
"names" : [ "MD048" , "code-fence-style" ] ,
"description" : "Code fence style" ,
"tags" : [ "code" ] ,
"function" : function MD048 ( params , onError ) {
2022-06-02 21:42:48 -07:00
const style = String ( params . config . style || "consistent" ) ;
let expectedStyle = style ;
2022-06-08 22:10:27 -07:00
const fenceTokens = params . tokens . filter ( ( token ) => token . type === "fence" ) ;
for ( const fenceToken of fenceTokens ) {
2022-06-02 21:42:48 -07:00
const { lineNumber , markup } = fenceToken ;
2019-12-14 13:50:48 -08:00
if ( expectedStyle === "consistent" ) {
expectedStyle = fencedCodeBlockStyleFor ( markup ) ;
}
addErrorDetailIf ( onError , lineNumber , expectedStyle , fencedCodeBlockStyleFor ( markup ) ) ;
2022-06-08 22:10:27 -07:00
}
2019-12-14 13:50:48 -08:00
}
} ;
2021-01-05 20:55:09 -08:00
2021-10-24 06:54:58 +02:00
/***/ } ) ,
2022-05-03 21:37:30 -07:00
/***/ "../lib/md049-md050.js" :
/ * ! * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ! * \
! * * * . . / lib / md049 - md050 . js * * * !
\ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
2021-10-24 06:54:58 +02:00
/***/ ( ( module , _ _unused _webpack _exports , _ _webpack _require _ _ ) => {
"use strict" ;
// @ts-check
2022-06-02 21:42:48 -07:00
const { addError , emphasisOrStrongStyleFor , forEachInlineChild , getNextChildToken , getRangeAndFixInfoIfFound } = _ _webpack _require _ _ ( /*! ../helpers */ "../helpers/helpers.js" ) ;
const impl = ( params , onError , tagPrefix , asterisk , underline , style ) => {
let lastLineNumber = - 1 ;
const instances = new Map ( ) ;
forEachInlineChild ( params , ` ${ tagPrefix } _open ` , ( token , parent ) => {
const { lineNumber , markup } = token ;
const markupStyle = emphasisOrStrongStyleFor ( markup ) ;
2022-05-03 21:59:49 -07:00
if ( style === "consistent" ) {
style = markupStyle ;
}
if ( style !== markupStyle ) {
2022-06-02 21:42:48 -07:00
let rangeAndFixInfo = { } ;
const contentToken = getNextChildToken ( parent , token , "text" , ` ${ tagPrefix } _close ` ) ;
2022-05-03 21:59:49 -07:00
if ( contentToken ) {
2022-06-02 21:42:48 -07:00
const { content } = contentToken ;
const actual = ` ${ markup } ${ content } ${ markup } ` ;
const expectedMarkup = ( style === "asterisk" ) ? asterisk : underline ;
const expected = ` ${ expectedMarkup } ${ content } ${ expectedMarkup } ` ;
2022-05-03 21:59:49 -07:00
if ( lastLineNumber !== lineNumber ) {
lastLineNumber = lineNumber ;
instances . clear ( ) ;
2021-11-28 23:18:57 -08:00
}
2022-06-02 21:42:48 -07:00
const instance = ( instances . get ( expected ) || 0 ) + 1 ;
2022-05-03 21:59:49 -07:00
instances . set ( expected , instance ) ;
rangeAndFixInfo = getRangeAndFixInfoIfFound ( params . lines , lineNumber - 1 , actual , expected , instance ) ;
2021-11-28 23:18:57 -08:00
}
2022-06-02 21:42:48 -07:00
addError ( onError , lineNumber , ` Expected: ${ style } ; Actual: ${ markupStyle } ` , null , rangeAndFixInfo . range , rangeAndFixInfo . fixInfo ) ;
2022-05-03 21:59:49 -07:00
}
} ) ;
2021-10-24 06:54:58 +02:00
} ;
2022-05-03 21:59:49 -07:00
module . exports = [
{
"names" : [ "MD049" , "emphasis-style" ] ,
"description" : "Emphasis style should be consistent" ,
"tags" : [ "emphasis" ] ,
"function" : function MD049 ( params , onError ) {
2022-06-02 21:42:48 -07:00
const style = String ( params . config . style || "consistent" ) ;
2022-05-03 21:59:49 -07:00
return impl ( params , onError , "em" , "*" , "_" , style ) ;
}
} ,
{
"names" : [ "MD050" , "strong-style" ] ,
"description" : "Strong style should be consistent" ,
"tags" : [ "emphasis" ] ,
"function" : function MD050 ( params , onError ) {
2022-06-02 21:42:48 -07:00
const style = String ( params . config . style || "consistent" ) ;
2022-05-03 21:59:49 -07:00
return impl ( params , onError , "strong" , "**" , "__" , style ) ;
}
2021-10-21 06:42:48 +02:00
}
2022-05-03 21:59:49 -07:00
] ;
2021-10-21 06:42:48 +02:00
2022-01-26 00:21:08 +01:00
/***/ } ) ,
/***/ "../lib/md051.js" :
/ * ! * * * * * * * * * * * * * * * * * * * * * * * ! * \
! * * * . . / lib / md051 . js * * * !
\ * * * * * * * * * * * * * * * * * * * * * * * /
/***/ ( ( module , _ _unused _webpack _exports , _ _webpack _require _ _ ) => {
"use strict" ;
// @ts-check
2022-06-02 21:42:48 -07:00
const { addError , escapeForRegExp , filterTokens , forEachInlineChild , forEachHeading , htmlElementRe } = _ _webpack _require _ _ ( /*! ../helpers */ "../helpers/helpers.js" ) ;
2022-04-10 05:37:57 +00:00
// Regular expression for identifying HTML anchor names
2022-07-28 00:42:05 -04:00
const idRe = /\sid\s*=\s*['"]?([^'"\s>]+)/iu ;
const nameRe = /\sname\s*=\s*['"]?([^'"\s>]+)/iu ;
2022-01-26 00:21:08 +01:00
/ * *
2022-04-10 05:37:57 +00:00
* Converts a Markdown heading into an HTML fragment according to the rules
* used by GitHub .
2022-01-26 00:21:08 +01:00
*
2022-04-10 05:37:57 +00:00
* @ param { Object } inline Inline token for heading .
* @ returns { string } Fragment string for heading .
2022-01-26 00:21:08 +01:00
* /
2022-04-10 05:37:57 +00:00
function convertHeadingToHTMLFragment ( inline ) {
2022-07-19 06:29:52 +00:00
const inlineText = inline . children
. filter ( ( token ) => token . type !== "html_inline" )
. map ( ( token ) => token . content )
. join ( "" ) ;
2022-04-18 20:59:01 -07:00
return "#" + encodeURIComponent ( inlineText
2022-01-26 00:21:08 +01:00
. toLowerCase ( )
2022-04-18 20:59:01 -07:00
// RegExp source with Ruby's \p{Word} expanded into its General Categories
// eslint-disable-next-line max-len
// https://github.com/gjtorikian/html-pipeline/blob/main/lib/html/pipeline/toc_filter.rb
// https://ruby-doc.org/core-3.0.2/Regexp.html
. replace ( /[^\p{Letter}\p{Mark}\p{Number}\p{Connector_Punctuation}\- ]/gu , "" )
. replace ( / /gu , "-" ) ) ;
2022-01-26 00:21:08 +01:00
}
module . exports = {
2022-04-10 05:37:57 +00:00
"names" : [ "MD051" , "link-fragments" ] ,
2022-01-26 00:21:08 +01:00
"description" : "Link fragments should be valid" ,
"tags" : [ "links" ] ,
"function" : function MD051 ( params , onError ) {
2022-06-02 21:42:48 -07:00
const fragments = new Map ( ) ;
2022-04-20 21:27:04 -07:00
// Process headings
2022-06-02 21:42:48 -07:00
forEachHeading ( params , ( heading , content , inline ) => {
const fragment = convertHeadingToHTMLFragment ( inline ) ;
const count = fragments . get ( fragment ) || 0 ;
2022-04-21 21:02:46 -07:00
if ( count ) {
2022-06-02 21:42:48 -07:00
fragments . set ( ` ${ fragment } - ${ count } ` , 0 ) ;
2022-04-21 21:02:46 -07:00
}
fragments . set ( fragment , count + 1 ) ;
2022-04-10 05:37:57 +00:00
} ) ;
2022-04-20 21:27:04 -07:00
// Process HTML anchors
2022-06-02 21:42:48 -07:00
const processHtmlToken = ( token ) => {
let match = null ;
2022-04-20 21:27:04 -07:00
while ( ( match = htmlElementRe . exec ( token . content ) ) !== null ) {
2022-06-02 21:42:48 -07:00
const [ tag , , element ] = match ;
2022-07-28 00:42:05 -04:00
const anchorMatch = idRe . exec ( tag ) ||
( element . toLowerCase ( ) === "a" && nameRe . exec ( tag ) ) ;
if ( anchorMatch ) {
fragments . set ( ` # ${ anchorMatch [ 1 ] } ` , 0 ) ;
2022-04-10 05:37:57 +00:00
}
}
2022-04-20 21:27:04 -07:00
} ;
filterTokens ( params , "html_block" , processHtmlToken ) ;
forEachInlineChild ( params , "html_inline" , processHtmlToken ) ;
// Process link fragments
2022-06-02 21:42:48 -07:00
forEachInlineChild ( params , "link_open" , ( token ) => {
const { attrs , lineNumber , line } = token ;
const href = attrs . find ( ( attr ) => attr [ 0 ] === "href" ) ;
const id = href && href [ 1 ] ;
2022-04-20 21:27:04 -07:00
if ( id && ( id . length > 1 ) && ( id [ 0 ] === "#" ) && ! fragments . has ( id ) ) {
2022-06-02 21:42:48 -07:00
let context = id ;
let range = null ;
const match = line . match ( new RegExp ( ` \\ [.*? \\ ] \\ ( ${ escapeForRegExp ( context ) } \\ ) ` ) ) ;
2022-04-20 21:27:04 -07:00
if ( match ) {
context = match [ 0 ] ;
range = [ match . index + 1 , match [ 0 ] . length ] ;
2022-01-26 00:21:08 +01:00
}
2022-07-19 06:29:52 +00:00
addError ( onError , lineNumber , undefined , context , range ) ;
2022-04-10 05:37:57 +00:00
}
2022-01-26 00:21:08 +01:00
} ) ;
}
} ;
2022-06-01 20:23:08 -07:00
/***/ } ) ,
/***/ "../lib/md052.js" :
/ * ! * * * * * * * * * * * * * * * * * * * * * * * ! * \
! * * * . . / lib / md052 . js * * * !
\ * * * * * * * * * * * * * * * * * * * * * * * /
/***/ ( ( module , _ _unused _webpack _exports , _ _webpack _require _ _ ) => {
"use strict" ;
// @ts-check
2022-06-02 21:42:48 -07:00
const { addError } = _ _webpack _require _ _ ( /*! ../helpers */ "../helpers/helpers.js" ) ;
const { referenceLinkImageData } = _ _webpack _require _ _ ( /*! ./cache */ "../lib/cache.js" ) ;
2022-06-01 20:23:08 -07:00
module . exports = {
"names" : [ "MD052" , "reference-links-images" ] ,
"description" : "Reference links and images should use a label that is defined" ,
"tags" : [ "images" , "links" ] ,
"function" : function MD052 ( params , onError ) {
2022-06-02 21:42:48 -07:00
const { lines } = params ;
const { references , definitions } = referenceLinkImageData ( ) ;
2022-06-01 20:23:08 -07:00
// Look for links/images that use an undefined link reference
2022-06-02 21:42:48 -07:00
for ( const reference of references . entries ( ) ) {
const [ label , datas ] = reference ;
2022-06-01 20:23:08 -07:00
if ( ! definitions . has ( label ) ) {
2022-06-02 21:42:48 -07:00
for ( const data of datas ) {
const [ lineIndex , index , length ] = data ;
2022-06-01 20:23:08 -07:00
// Context will be incomplete if reporting for a multi-line link
2022-06-02 21:42:48 -07:00
const context = lines [ lineIndex ] . slice ( index , index + length ) ;
addError ( onError , lineIndex + 1 , ` Missing link or image reference definition: " ${ label } " ` , context , [ index + 1 , context . length ] ) ;
2022-06-01 20:23:08 -07:00
}
}
}
}
} ;
/***/ } ) ,
/***/ "../lib/md053.js" :
/ * ! * * * * * * * * * * * * * * * * * * * * * * * ! * \
! * * * . . / lib / md053 . js * * * !
\ * * * * * * * * * * * * * * * * * * * * * * * /
/***/ ( ( module , _ _unused _webpack _exports , _ _webpack _require _ _ ) => {
"use strict" ;
// @ts-check
2022-06-02 21:42:48 -07:00
const { addError , ellipsify , linkReferenceDefinitionRe } = _ _webpack _require _ _ ( /*! ../helpers */ "../helpers/helpers.js" ) ;
const { referenceLinkImageData } = _ _webpack _require _ _ ( /*! ./cache */ "../lib/cache.js" ) ;
2022-06-01 20:23:08 -07:00
module . exports = {
"names" : [ "MD053" , "link-image-reference-definitions" ] ,
"description" : "Link and image reference definitions should be needed" ,
"tags" : [ "images" , "links" ] ,
"function" : function MD053 ( params , onError ) {
2022-08-02 20:36:47 -07:00
const ignored = new Set ( params . config . ignored _definitions || [ "//" ] ) ;
const lines = params . lines ;
2022-06-02 21:42:48 -07:00
const { references , shortcuts , definitions , duplicateDefinitions } = referenceLinkImageData ( ) ;
const singleLineDefinition = ( line ) => ( line . replace ( linkReferenceDefinitionRe , "" ) . trim ( ) . length > 0 ) ;
const deleteFixInfo = {
2022-06-01 20:23:08 -07:00
"deleteCount" : - 1
} ;
// Look for unused link references (unreferenced by any link/image)
2022-06-02 21:42:48 -07:00
for ( const definition of definitions . entries ( ) ) {
const [ label , lineIndex ] = definition ;
2022-08-02 20:36:47 -07:00
if ( ! ignored . has ( label ) &&
! references . has ( label ) &&
! shortcuts . has ( label ) ) {
2022-06-02 21:42:48 -07:00
const line = lines [ lineIndex ] ;
addError ( onError , lineIndex + 1 , ` Unused link or image reference definition: " ${ label } " ` , ellipsify ( line ) , [ 1 , line . length ] , singleLineDefinition ( line ) ? deleteFixInfo : 0 ) ;
2022-06-01 20:23:08 -07:00
}
}
// Look for duplicate link references (defined more than once)
2022-06-02 21:42:48 -07:00
for ( const duplicateDefinition of duplicateDefinitions ) {
const [ label , lineIndex ] = duplicateDefinition ;
2022-08-02 20:36:47 -07:00
if ( ! ignored . has ( label ) ) {
const line = lines [ lineIndex ] ;
addError ( onError , lineIndex + 1 , ` Duplicate link or image reference definition: " ${ label } " ` , ellipsify ( line ) , [ 1 , line . length ] , singleLineDefinition ( line ) ? deleteFixInfo : 0 ) ;
}
2022-06-01 20:23:08 -07:00
}
}
} ;
2021-01-05 20:55:09 -08:00
/***/ } ) ,
2021-01-06 19:45:15 -08:00
/***/ "../lib/rules.js" :
/ * ! * * * * * * * * * * * * * * * * * * * * * * * ! * \
! * * * . . / lib / rules . js * * * !
\ * * * * * * * * * * * * * * * * * * * * * * * /
2022-06-02 21:42:48 -07:00
/***/ ( ( module , _ _unused _webpack _exports , _ _webpack _require _ _ ) => {
2021-01-05 20:55:09 -08:00
2019-12-14 13:50:48 -08:00
"use strict" ;
2021-01-05 20:55:09 -08:00
// @ts-check
2022-06-02 21:42:48 -07:00
const { homepage , version } = _ _webpack _require _ _ ( /*! ./constants */ "../lib/constants.js" ) ;
const rules = [
2021-01-06 19:45:15 -08:00
_ _webpack _require _ _ ( /*! ./md001 */ "../lib/md001.js" ) ,
_ _webpack _require _ _ ( /*! ./md002 */ "../lib/md002.js" ) ,
_ _webpack _require _ _ ( /*! ./md003 */ "../lib/md003.js" ) ,
_ _webpack _require _ _ ( /*! ./md004 */ "../lib/md004.js" ) ,
_ _webpack _require _ _ ( /*! ./md005 */ "../lib/md005.js" ) ,
_ _webpack _require _ _ ( /*! ./md006 */ "../lib/md006.js" ) ,
_ _webpack _require _ _ ( /*! ./md007 */ "../lib/md007.js" ) ,
_ _webpack _require _ _ ( /*! ./md009 */ "../lib/md009.js" ) ,
_ _webpack _require _ _ ( /*! ./md010 */ "../lib/md010.js" ) ,
_ _webpack _require _ _ ( /*! ./md011 */ "../lib/md011.js" ) ,
_ _webpack _require _ _ ( /*! ./md012 */ "../lib/md012.js" ) ,
_ _webpack _require _ _ ( /*! ./md013 */ "../lib/md013.js" ) ,
_ _webpack _require _ _ ( /*! ./md014 */ "../lib/md014.js" ) ,
_ _webpack _require _ _ ( /*! ./md018 */ "../lib/md018.js" ) ,
_ _webpack _require _ _ ( /*! ./md019 */ "../lib/md019.js" ) ,
_ _webpack _require _ _ ( /*! ./md020 */ "../lib/md020.js" ) ,
_ _webpack _require _ _ ( /*! ./md021 */ "../lib/md021.js" ) ,
_ _webpack _require _ _ ( /*! ./md022 */ "../lib/md022.js" ) ,
_ _webpack _require _ _ ( /*! ./md023 */ "../lib/md023.js" ) ,
_ _webpack _require _ _ ( /*! ./md024 */ "../lib/md024.js" ) ,
_ _webpack _require _ _ ( /*! ./md025 */ "../lib/md025.js" ) ,
_ _webpack _require _ _ ( /*! ./md026 */ "../lib/md026.js" ) ,
_ _webpack _require _ _ ( /*! ./md027 */ "../lib/md027.js" ) ,
_ _webpack _require _ _ ( /*! ./md028 */ "../lib/md028.js" ) ,
_ _webpack _require _ _ ( /*! ./md029 */ "../lib/md029.js" ) ,
_ _webpack _require _ _ ( /*! ./md030 */ "../lib/md030.js" ) ,
_ _webpack _require _ _ ( /*! ./md031 */ "../lib/md031.js" ) ,
_ _webpack _require _ _ ( /*! ./md032 */ "../lib/md032.js" ) ,
_ _webpack _require _ _ ( /*! ./md033 */ "../lib/md033.js" ) ,
_ _webpack _require _ _ ( /*! ./md034 */ "../lib/md034.js" ) ,
_ _webpack _require _ _ ( /*! ./md035 */ "../lib/md035.js" ) ,
_ _webpack _require _ _ ( /*! ./md036 */ "../lib/md036.js" ) ,
_ _webpack _require _ _ ( /*! ./md037 */ "../lib/md037.js" ) ,
_ _webpack _require _ _ ( /*! ./md038 */ "../lib/md038.js" ) ,
_ _webpack _require _ _ ( /*! ./md039 */ "../lib/md039.js" ) ,
_ _webpack _require _ _ ( /*! ./md040 */ "../lib/md040.js" ) ,
_ _webpack _require _ _ ( /*! ./md041 */ "../lib/md041.js" ) ,
_ _webpack _require _ _ ( /*! ./md042 */ "../lib/md042.js" ) ,
_ _webpack _require _ _ ( /*! ./md043 */ "../lib/md043.js" ) ,
_ _webpack _require _ _ ( /*! ./md044 */ "../lib/md044.js" ) ,
_ _webpack _require _ _ ( /*! ./md045 */ "../lib/md045.js" ) ,
_ _webpack _require _ _ ( /*! ./md046 */ "../lib/md046.js" ) ,
_ _webpack _require _ _ ( /*! ./md047 */ "../lib/md047.js" ) ,
2022-06-02 21:42:48 -07:00
_ _webpack _require _ _ ( /*! ./md048 */ "../lib/md048.js" ) ,
... _ _webpack _require _ _ ( /*! ./md049-md050 */ "../lib/md049-md050.js" ) ,
2022-06-01 20:23:08 -07:00
_ _webpack _require _ _ ( /*! ./md051 */ "../lib/md051.js" ) ,
_ _webpack _require _ _ ( /*! ./md052 */ "../lib/md052.js" ) ,
_ _webpack _require _ _ ( /*! ./md053 */ "../lib/md053.js" )
2022-06-02 21:42:48 -07:00
] ;
2022-06-08 22:10:27 -07:00
for ( const rule of rules ) {
2022-06-02 21:42:48 -07:00
const name = rule . names [ 0 ] . toLowerCase ( ) ;
2021-01-06 20:20:18 -08:00
// eslint-disable-next-line dot-notation
rule [ "information" ] =
2022-06-02 21:42:48 -07:00
new URL ( ` ${ homepage } /blob/v ${ version } /doc/Rules.md# ${ name } ` ) ;
2022-06-08 22:10:27 -07:00
}
2019-10-02 20:10:42 -07:00
module . exports = rules ;
2021-01-05 20:55:09 -08:00
/***/ } )
/******/ } ) ;
/************************************************************************/
/******/ // The module cache
/******/ var _ _webpack _module _cache _ _ = { } ;
/******/
/******/ // The require function
/******/ function _ _webpack _require _ _ ( moduleId ) {
/******/ // Check if module is in cache
Update dependencies: c8 to 7.7.2, eslint to 7.28.0, eslint-plugin-jsdoc to 35.1.3, eslint-plugin-unicorn to 33.0.1, globby to 11.0.3, js-yaml to 4.1.0, markdown-it-texmath to 0.9.0, markdownlint-rule-helpers to 0.14.0, ts-loader to 9.2.3, typescript to 4.3.2, webpack to 5.38.1, webpack-cli to 4.7.2.
2021-06-08 22:20:13 -07:00
/******/ var cachedModule = _ _webpack _module _cache _ _ [ moduleId ] ;
/******/ if ( cachedModule !== undefined ) {
/******/ return cachedModule . exports ;
2021-01-05 20:55:09 -08:00
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = _ _webpack _module _cache _ _ [ moduleId ] = {
/******/ // no module.id needed
/******/ // no module.loaded needed
/******/ exports : { }
/******/ } ;
/******/
/******/ // Execute the module function
2022-06-02 21:42:48 -07:00
/******/ _ _webpack _modules _ _ [ moduleId ] ( module , module . exports , _ _webpack _require _ _ ) ;
2021-01-05 20:55:09 -08:00
/******/
/******/ // Return the exports of the module
/******/ return module . exports ;
/******/ }
/******/
/************************************************************************/
/******/ /* webpack/runtime/hasOwnProperty shorthand */
/******/ ( ( ) => {
2021-02-06 19:23:55 -08:00
/******/ _ _webpack _require _ _ . o = ( obj , prop ) => ( Object . prototype . hasOwnProperty . call ( obj , prop ) )
2021-01-05 20:55:09 -08:00
/******/ } ) ( ) ;
/******/
/************************************************************************/
Update dependencies: c8 to 7.7.2, eslint to 7.28.0, eslint-plugin-jsdoc to 35.1.3, eslint-plugin-unicorn to 33.0.1, globby to 11.0.3, js-yaml to 4.1.0, markdown-it-texmath to 0.9.0, markdownlint-rule-helpers to 0.14.0, ts-loader to 9.2.3, typescript to 4.3.2, webpack to 5.38.1, webpack-cli to 4.7.2.
2021-06-08 22:20:13 -07:00
/******/
2021-01-05 20:55:09 -08:00
/******/ // startup
/******/ // Load entry module and return exports
Update dependencies: c8 to 7.7.2, eslint to 7.28.0, eslint-plugin-jsdoc to 35.1.3, eslint-plugin-unicorn to 33.0.1, globby to 11.0.3, js-yaml to 4.1.0, markdown-it-texmath to 0.9.0, markdownlint-rule-helpers to 0.14.0, ts-loader to 9.2.3, typescript to 4.3.2, webpack to 5.38.1, webpack-cli to 4.7.2.
2021-06-08 22:20:13 -07:00
/******/ // This entry module is referenced by other modules so it can't be inlined
/******/ var _ _webpack _exports _ _ = _ _webpack _require _ _ ( "../lib/markdownlint.js" ) ;
/******/ markdownlint = _ _webpack _exports _ _ ;
/******/
2021-01-05 20:55:09 -08:00
/******/ } ) ( )
;