mirror of
https://github.com/remarkjs/remark-lint.git
synced 2024-08-17 07:40:31 +03:00
Add JSDoc based types
This commit is contained in:
parent
5c215ec00b
commit
1a1e7cc586
74
.gitignore
vendored
74
.gitignore
vendored
@ -1,6 +1,80 @@
|
||||
coverage/
|
||||
node_modules/
|
||||
.DS_Store
|
||||
/packages/remark-lint/*.d.ts
|
||||
/packages/remark-lint-blockquote-indentation/*.d.ts
|
||||
/packages/remark-lint-checkbox-character-style/*.d.ts
|
||||
/packages/remark-lint-checkbox-content-indent/*.d.ts
|
||||
/packages/remark-lint-code-block-style/*.d.ts
|
||||
/packages/remark-lint-definition-case/*.d.ts
|
||||
/packages/remark-lint-definition-spacing/*.d.ts
|
||||
/packages/remark-lint-emphasis-marker/*.d.ts
|
||||
/packages/remark-lint-fenced-code-flag/*.d.ts
|
||||
/packages/remark-lint-fenced-code-marker/*.d.ts
|
||||
/packages/remark-lint-file-extension/*.d.ts
|
||||
/packages/remark-lint-final-definition/*.d.ts
|
||||
/packages/remark-lint-final-newline/*.d.ts
|
||||
/packages/remark-lint-first-heading-level/*.d.ts
|
||||
/packages/remark-lint-hard-break-spaces/*.d.ts
|
||||
/packages/remark-lint-heading-increment/*.d.ts
|
||||
/packages/remark-lint-heading-style/*.d.ts
|
||||
/packages/remark-lint-linebreak-style/*.d.ts
|
||||
/packages/remark-lint-link-title-style/*.d.ts
|
||||
/packages/remark-lint-list-item-bullet-indent/*.d.ts
|
||||
/packages/remark-lint-list-item-content-indent/*.d.ts
|
||||
/packages/remark-lint-list-item-indent/*.d.ts
|
||||
/packages/remark-lint-list-item-spacing/*.d.ts
|
||||
/packages/remark-lint-maximum-heading-length/*.d.ts
|
||||
/packages/remark-lint-maximum-line-length/*.d.ts
|
||||
/packages/remark-lint-no-auto-link-without-protocol/*.d.ts
|
||||
/packages/remark-lint-no-blockquote-without-marker/*.d.ts
|
||||
/packages/remark-lint-no-consecutive-blank-lines/*.d.ts
|
||||
/packages/remark-lint-no-duplicate-defined-urls/*.d.ts
|
||||
/packages/remark-lint-no-duplicate-definitions/*.d.ts
|
||||
/packages/remark-lint-no-duplicate-headings/*.d.ts
|
||||
/packages/remark-lint-no-duplicate-headings-in-section/*.d.ts
|
||||
/packages/remark-lint-no-emphasis-as-heading/*.d.ts
|
||||
/packages/remark-lint-no-empty-url/*.d.ts
|
||||
/packages/remark-lint-no-file-name-articles/*.d.ts
|
||||
/packages/remark-lint-no-file-name-consecutive-dashes/*.d.ts
|
||||
/packages/remark-lint-no-file-name-irregular-characters/*.d.ts
|
||||
/packages/remark-lint-no-file-name-mixed-case/*.d.ts
|
||||
/packages/remark-lint-no-file-name-outer-dashes/*.d.ts
|
||||
/packages/remark-lint-no-heading-content-indent/*.d.ts
|
||||
/packages/remark-lint-no-heading-indent/*.d.ts
|
||||
/packages/remark-lint-no-heading-like-paragraph/*.d.ts
|
||||
/packages/remark-lint-no-heading-punctuation/*.d.ts
|
||||
/packages/remark-lint-no-html/*.d.ts
|
||||
/packages/remark-lint-no-inline-padding/*.d.ts
|
||||
/packages/remark-lint-no-literal-urls/*.d.ts
|
||||
/packages/remark-lint-no-missing-blank-lines/*.d.ts
|
||||
/packages/remark-lint-no-multiple-toplevel-headings/*.d.ts
|
||||
/packages/remark-lint-no-paragraph-content-indent/*.d.ts
|
||||
/packages/remark-lint-no-reference-like-url/*.d.ts
|
||||
/packages/remark-lint-no-shell-dollars/*.d.ts
|
||||
/packages/remark-lint-no-shortcut-reference-image/*.d.ts
|
||||
/packages/remark-lint-no-shortcut-reference-link/*.d.ts
|
||||
/packages/remark-lint-no-table-indentation/*.d.ts
|
||||
/packages/remark-lint-no-tabs/*.d.ts
|
||||
/packages/remark-lint-no-undefined-references/*.d.ts
|
||||
/packages/remark-lint-no-unneeded-full-reference-image/*.d.ts
|
||||
/packages/remark-lint-no-unneeded-full-reference-link/*.d.ts
|
||||
/packages/remark-lint-no-unused-definitions/*.d.ts
|
||||
/packages/remark-lint-ordered-list-marker-style/*.d.ts
|
||||
/packages/remark-lint-ordered-list-marker-value/*.d.ts
|
||||
/packages/remark-lint-rule-style/*.d.ts
|
||||
/packages/remark-lint-strikethrough-marker/*.d.ts
|
||||
/packages/remark-lint-strong-marker/*.d.ts
|
||||
/packages/remark-lint-table-cell-padding/*.d.ts
|
||||
/packages/remark-lint-table-pipe-alignment/*.d.ts
|
||||
/packages/remark-lint-table-pipes/*.d.ts
|
||||
/packages/remark-lint-unordered-list-marker-style/*.d.ts
|
||||
/packages/remark-preset-lint-consistent/*.d.ts
|
||||
/packages/remark-preset-lint-markdown-style-guide/*.d.ts
|
||||
/packages/remark-preset-lint-recommended/*.d.ts
|
||||
/packages/unified-lint-rule/lib/*.d.ts
|
||||
/script/**/*.d.ts
|
||||
/*.d.ts
|
||||
*.log
|
||||
package-lock.json
|
||||
yarn.lock
|
||||
|
23
package.json
23
package.json
@ -33,6 +33,10 @@
|
||||
],
|
||||
"type": "module",
|
||||
"devDependencies": {
|
||||
"@types/mdast": "^3.0.0",
|
||||
"@types/parse-author": "^2.0.0",
|
||||
"@types/pluralize": "^0.0.29",
|
||||
"@types/tape": "^4.0.0",
|
||||
"c8": "^7.0.0",
|
||||
"comment-parser": "^1.0.0",
|
||||
"lerna": "^4.0.0",
|
||||
@ -46,22 +50,27 @@
|
||||
"remark-github": "^11.0.0",
|
||||
"remark-toc": "^8.0.0",
|
||||
"remark-validate-links": "^11.0.0",
|
||||
"rimraf": "^3.0.0",
|
||||
"strip-indent": "^4.0.0",
|
||||
"tape": "^5.0.0",
|
||||
"to-vfile": "^7.0.0",
|
||||
"type-coverage": "^2.0.0",
|
||||
"type-fest": "^2.0.0",
|
||||
"typescript": "^4.0.0",
|
||||
"unist-builder": "^3.0.0",
|
||||
"unist-util-remove-position": "^4.0.0",
|
||||
"xo": "^0.39.0"
|
||||
},
|
||||
"scripts": {
|
||||
"postinstall": "lerna bootstrap --no-ci",
|
||||
"build-packages": "node script/build-presets && node script/build-rules",
|
||||
"build-workspace": "lerna run build",
|
||||
"build-monorepo": "rimraf \"test.d.ts\" \"script/**/*.d.ts\" && tsc && type-coverage",
|
||||
"build": "npm run build-packages && npm run build-workspace && npm run build-monorepo",
|
||||
"format": "remark . -qfo && prettier . -w --loglevel warn && xo --fix",
|
||||
"generate:presets": "node script/build-presets",
|
||||
"generate:rules": "node script/build-rules",
|
||||
"generate": "npm run generate:presets && npm run generate:rules",
|
||||
"test-api": "node --conditions development test.js",
|
||||
"test-coverage": "c8 --check-coverage --branches 100 --functions 100 --lines 100 --statements 100 --reporter lcov npm run test-api",
|
||||
"test": "npm run generate && npm run format && npm run test-coverage"
|
||||
"test": "npm run build && npm run format && npm run test-coverage"
|
||||
},
|
||||
"prettier": {
|
||||
"tabWidth": 2,
|
||||
@ -88,5 +97,11 @@
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"typeCoverage": {
|
||||
"atLeast": 100,
|
||||
"detail": true,
|
||||
"strict": true,
|
||||
"ignoreCatch": true
|
||||
}
|
||||
}
|
||||
|
@ -48,6 +48,12 @@
|
||||
* 9:3: Add 1 space between block quote and content
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {import('mdast').Root} Root
|
||||
* @typedef {import('mdast').Blockquote} Blockquote
|
||||
* @typedef {'consistent'|number} Options
|
||||
*/
|
||||
|
||||
import {lintRule} from 'unified-lint-rule'
|
||||
import plural from 'pluralize'
|
||||
import {visit} from 'unist-util-visit'
|
||||
@ -56,41 +62,42 @@ import {generated} from 'unist-util-generated'
|
||||
|
||||
const remarkLintBlockquoteIndentation = lintRule(
|
||||
'remark-lint:blockquote-indentation',
|
||||
blockquoteIndentation
|
||||
/** @type {import('unified-lint-rule').Rule<Root, Options>} */
|
||||
(tree, file, option = 'consistent') => {
|
||||
visit(tree, 'blockquote', (node) => {
|
||||
if (generated(node) || node.children.length === 0) {
|
||||
return
|
||||
}
|
||||
|
||||
if (option === 'consistent') {
|
||||
option = check(node)
|
||||
} else {
|
||||
const diff = option - check(node)
|
||||
|
||||
if (diff !== 0) {
|
||||
const abs = Math.abs(diff)
|
||||
|
||||
file.message(
|
||||
(diff > 0 ? 'Add' : 'Remove') +
|
||||
' ' +
|
||||
abs +
|
||||
' ' +
|
||||
plural('space', abs) +
|
||||
' between block quote and content',
|
||||
pointStart(node.children[0])
|
||||
)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
)
|
||||
|
||||
export default remarkLintBlockquoteIndentation
|
||||
|
||||
function blockquoteIndentation(tree, file, option) {
|
||||
let preferred = typeof option === 'number' ? option : null
|
||||
|
||||
visit(tree, 'blockquote', (node) => {
|
||||
if (generated(node) || node.children.length === 0) {
|
||||
return
|
||||
}
|
||||
|
||||
if (preferred) {
|
||||
const diff = preferred - check(node)
|
||||
|
||||
if (diff !== 0) {
|
||||
const abs = Math.abs(diff)
|
||||
|
||||
file.message(
|
||||
(diff > 0 ? 'Add' : 'Remove') +
|
||||
' ' +
|
||||
abs +
|
||||
' ' +
|
||||
plural('space', abs) +
|
||||
' between block quote and content',
|
||||
pointStart(node.children[0])
|
||||
)
|
||||
}
|
||||
} else {
|
||||
preferred = check(node)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Blockquote} node
|
||||
* @returns {number}
|
||||
*/
|
||||
function check(node) {
|
||||
return pointStart(node.children[0]).column - pointStart(node).column
|
||||
}
|
||||
|
@ -25,15 +25,28 @@
|
||||
"sideEffects": false,
|
||||
"type": "module",
|
||||
"main": "index.js",
|
||||
"types": "index.d.ts",
|
||||
"files": [
|
||||
"index.d.ts",
|
||||
"index.js"
|
||||
],
|
||||
"dependencies": {
|
||||
"@types/mdast": "^3.0.0",
|
||||
"pluralize": "^8.0.0",
|
||||
"unified": "^10.0.0",
|
||||
"unified-lint-rule": "^1.0.0",
|
||||
"unist-util-generated": "^2.0.0",
|
||||
"unist-util-position": "^4.0.0",
|
||||
"unist-util-visit": "^4.0.0"
|
||||
},
|
||||
"xo": false
|
||||
"scripts": {
|
||||
"build": "rimraf \"*.d.ts\" && tsc && type-coverage"
|
||||
},
|
||||
"xo": false,
|
||||
"typeCoverage": {
|
||||
"atLeast": 100,
|
||||
"detail": true,
|
||||
"strict": true,
|
||||
"ignoreCatch": true
|
||||
}
|
||||
}
|
||||
|
@ -89,12 +89,18 @@ Paragraph.
|
||||
|
||||
## Install
|
||||
|
||||
This package is [ESM only][esm]:
|
||||
Node 12+ is needed to use it and it must be `imported`ed instead of `required`d.
|
||||
|
||||
[npm][]:
|
||||
|
||||
```sh
|
||||
npm install remark-lint-blockquote-indentation
|
||||
```
|
||||
|
||||
This package exports no identifiers.
|
||||
The default export is `remarkLintBlockquoteIndentation`.
|
||||
|
||||
## Use
|
||||
|
||||
You probably want to use it on the CLI through a config file:
|
||||
@ -175,6 +181,8 @@ abide by its terms.
|
||||
|
||||
[chat]: https://github.com/remarkjs/remark/discussions
|
||||
|
||||
[esm]: https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c
|
||||
|
||||
[npm]: https://docs.npmjs.com/cli/install
|
||||
|
||||
[health]: https://github.com/remarkjs/.github
|
||||
|
@ -0,0 +1,4 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"include": ["*.js"]
|
||||
}
|
@ -77,49 +77,65 @@
|
||||
* 1:1: Incorrect checked checkbox marker `💩`: use either `'x'`, or `'X'`
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {import('mdast').Root} Root
|
||||
*
|
||||
* @typedef Styles
|
||||
* @property {'x'|'X'|'consistent'} [checked='consistent']
|
||||
* @property {' '|'\x09'|'consistent'} [unchecked='consistent']
|
||||
*
|
||||
* @typedef {'consistent'|Styles} Options
|
||||
*/
|
||||
|
||||
import {lintRule} from 'unified-lint-rule'
|
||||
import {visit} from 'unist-util-visit'
|
||||
import {pointStart} from 'unist-util-position'
|
||||
import {generated} from 'unist-util-generated'
|
||||
|
||||
const checked = {x: true, X: true}
|
||||
const unchecked = {' ': true, '\t': true}
|
||||
const types = {true: 'checked', false: 'unchecked'}
|
||||
|
||||
const remarkLintCheckboxCharacterStyle = lintRule(
|
||||
'remark-lint:checkbox-character-style',
|
||||
(tree, file, option) => {
|
||||
/** @type {import('unified-lint-rule').Rule<Root, Options>} */
|
||||
(tree, file, option = 'consistent') => {
|
||||
const value = String(file)
|
||||
const preferred = typeof option === 'object' ? option : {}
|
||||
/** @type {'x'|'X'|'consistent'} */
|
||||
let checked = 'consistent'
|
||||
/** @type {' '|'\x09'|'consistent'} */
|
||||
let unchecked = 'consistent'
|
||||
|
||||
if (preferred.unchecked && unchecked[preferred.unchecked] !== true) {
|
||||
if (typeof option === 'object') {
|
||||
checked = option.checked || 'consistent'
|
||||
unchecked = option.unchecked || 'consistent'
|
||||
}
|
||||
|
||||
if (unchecked !== 'consistent' && unchecked !== ' ' && unchecked !== '\t') {
|
||||
file.fail(
|
||||
'Incorrect unchecked checkbox marker `' +
|
||||
preferred.unchecked +
|
||||
unchecked +
|
||||
"`: use either `'\\t'`, or `' '`"
|
||||
)
|
||||
}
|
||||
|
||||
if (preferred.checked && checked[preferred.checked] !== true) {
|
||||
if (checked !== 'consistent' && checked !== 'x' && checked !== 'X') {
|
||||
file.fail(
|
||||
'Incorrect checked checkbox marker `' +
|
||||
preferred.checked +
|
||||
checked +
|
||||
"`: use either `'x'`, or `'X'`"
|
||||
)
|
||||
}
|
||||
|
||||
visit(tree, 'listItem', (node) => {
|
||||
const head = node.children[0]
|
||||
const point = pointStart(head)
|
||||
|
||||
// Exit early for items without checkbox.
|
||||
// A list item cannot be checked and empty, according to GFM.
|
||||
if (typeof node.checked !== 'boolean' || generated(node) || !head) {
|
||||
if (
|
||||
typeof node.checked !== 'boolean' ||
|
||||
!head ||
|
||||
typeof point.offset !== 'number'
|
||||
) {
|
||||
return
|
||||
}
|
||||
|
||||
const type = types[node.checked]
|
||||
|
||||
const point = pointStart(head)
|
||||
|
||||
// Move back to before `] `.
|
||||
point.offset -= 2
|
||||
point.column -= 2
|
||||
@ -133,21 +149,24 @@ const remarkLintCheckboxCharacterStyle = lintRule(
|
||||
/* c8 ignore next */
|
||||
if (!match) return
|
||||
|
||||
const style = preferred[type]
|
||||
const style = node.checked ? checked : unchecked
|
||||
|
||||
if (style) {
|
||||
if (match[1] !== style) {
|
||||
file.message(
|
||||
type.charAt(0).toUpperCase() +
|
||||
type.slice(1) +
|
||||
' checkboxes should use `' +
|
||||
style +
|
||||
'` as a marker',
|
||||
point
|
||||
)
|
||||
if (style === 'consistent') {
|
||||
if (node.checked) {
|
||||
// @ts-expect-error: valid marker.
|
||||
checked = match[1]
|
||||
} else {
|
||||
// @ts-expect-error: valid marker.
|
||||
unchecked = match[1]
|
||||
}
|
||||
} else {
|
||||
preferred[type] = match[1]
|
||||
} else if (match[1] !== style) {
|
||||
file.message(
|
||||
(node.checked ? 'Checked' : 'Unchecked') +
|
||||
' checkboxes should use `' +
|
||||
style +
|
||||
'` as a marker',
|
||||
point
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -26,14 +26,26 @@
|
||||
"sideEffects": false,
|
||||
"type": "module",
|
||||
"main": "index.js",
|
||||
"types": "index.d.ts",
|
||||
"files": [
|
||||
"index.d.ts",
|
||||
"index.js"
|
||||
],
|
||||
"dependencies": {
|
||||
"@types/mdast": "^3.0.0",
|
||||
"unified": "^10.0.0",
|
||||
"unified-lint-rule": "^1.0.0",
|
||||
"unist-util-generated": "^2.0.0",
|
||||
"unist-util-position": "^4.0.0",
|
||||
"unist-util-visit": "^4.0.0"
|
||||
},
|
||||
"xo": false
|
||||
"scripts": {
|
||||
"build": "rimraf \"*.d.ts\" && tsc && type-coverage"
|
||||
},
|
||||
"xo": false,
|
||||
"typeCoverage": {
|
||||
"atLeast": 100,
|
||||
"detail": true,
|
||||
"strict": true,
|
||||
"ignoreCatch": true
|
||||
}
|
||||
}
|
||||
|
@ -160,12 +160,18 @@ When configured with `{ checked: '💩' }`.
|
||||
|
||||
## Install
|
||||
|
||||
This package is [ESM only][esm]:
|
||||
Node 12+ is needed to use it and it must be `imported`ed instead of `required`d.
|
||||
|
||||
[npm][]:
|
||||
|
||||
```sh
|
||||
npm install remark-lint-checkbox-character-style
|
||||
```
|
||||
|
||||
This package exports no identifiers.
|
||||
The default export is `remarkLintCheckboxCharacterStyle`.
|
||||
|
||||
## Use
|
||||
|
||||
You probably want to use it on the CLI through a config file:
|
||||
@ -246,6 +252,8 @@ abide by its terms.
|
||||
|
||||
[chat]: https://github.com/remarkjs/remark/discussions
|
||||
|
||||
[esm]: https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c
|
||||
|
||||
[npm]: https://docs.npmjs.com/cli/install
|
||||
|
||||
[health]: https://github.com/remarkjs/.github
|
||||
|
@ -0,0 +1,4 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"include": ["*.js"]
|
||||
}
|
@ -30,29 +30,36 @@
|
||||
* 4:7-4:10: Checkboxes should be followed by a single character
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {import('mdast').Root} Root
|
||||
*/
|
||||
|
||||
import {lintRule} from 'unified-lint-rule'
|
||||
import {location} from 'vfile-location'
|
||||
import {visit} from 'unist-util-visit'
|
||||
import {pointStart} from 'unist-util-position'
|
||||
import {generated} from 'unist-util-generated'
|
||||
|
||||
const remarkLintCheckboxContentIndent = lintRule(
|
||||
'remark-lint:checkbox-content-indent',
|
||||
/** @type {import('unified-lint-rule').Rule<Root, void>} */
|
||||
(tree, file) => {
|
||||
const value = String(file)
|
||||
const loc = location(file)
|
||||
|
||||
visit(tree, 'listItem', (node) => {
|
||||
const head = node.children[0]
|
||||
const point = pointStart(head)
|
||||
|
||||
// Exit early for items without checkbox.
|
||||
// A list item cannot be checked and empty, according to GFM.
|
||||
if (typeof node.checked !== 'boolean' || generated(node) || !head) {
|
||||
if (
|
||||
typeof node.checked !== 'boolean' ||
|
||||
!head ||
|
||||
typeof point.offset !== 'number'
|
||||
) {
|
||||
return
|
||||
}
|
||||
|
||||
const point = pointStart(head)
|
||||
|
||||
// Assume we start with a checkbox, because well, `checked` is set.
|
||||
const match = /\[([\t xX])]/.exec(
|
||||
value.slice(point.offset - 4, point.offset + 1)
|
||||
|
@ -26,15 +26,27 @@
|
||||
"sideEffects": false,
|
||||
"type": "module",
|
||||
"main": "index.js",
|
||||
"types": "index.d.ts",
|
||||
"files": [
|
||||
"index.d.ts",
|
||||
"index.js"
|
||||
],
|
||||
"dependencies": {
|
||||
"@types/mdast": "^3.0.0",
|
||||
"unified": "^10.0.0",
|
||||
"unified-lint-rule": "^1.0.0",
|
||||
"unist-util-generated": "^2.0.0",
|
||||
"unist-util-position": "^4.0.0",
|
||||
"unist-util-visit": "^4.0.0",
|
||||
"vfile-location": "^4.0.0"
|
||||
},
|
||||
"xo": false
|
||||
"scripts": {
|
||||
"build": "rimraf \"*.d.ts\" && tsc && type-coverage"
|
||||
},
|
||||
"xo": false,
|
||||
"typeCoverage": {
|
||||
"atLeast": 100,
|
||||
"detail": true,
|
||||
"strict": true,
|
||||
"ignoreCatch": true
|
||||
}
|
||||
}
|
||||
|
@ -58,12 +58,18 @@ Note: this example uses [GFM][].
|
||||
|
||||
## Install
|
||||
|
||||
This package is [ESM only][esm]:
|
||||
Node 12+ is needed to use it and it must be `imported`ed instead of `required`d.
|
||||
|
||||
[npm][]:
|
||||
|
||||
```sh
|
||||
npm install remark-lint-checkbox-content-indent
|
||||
```
|
||||
|
||||
This package exports no identifiers.
|
||||
The default export is `remarkLintCheckboxContentIndent`.
|
||||
|
||||
## Use
|
||||
|
||||
You probably want to use it on the CLI through a config file:
|
||||
@ -144,6 +150,8 @@ abide by its terms.
|
||||
|
||||
[chat]: https://github.com/remarkjs/remark/discussions
|
||||
|
||||
[esm]: https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c
|
||||
|
||||
[npm]: https://docs.npmjs.com/cli/install
|
||||
|
||||
[health]: https://github.com/remarkjs/.github
|
||||
|
@ -0,0 +1,4 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"include": ["*.js"]
|
||||
}
|
@ -101,52 +101,55 @@
|
||||
* 1:1: Incorrect code block style `💩`: use either `'consistent'`, `'fenced'`, or `'indented'`
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {import('mdast').Root} Root
|
||||
* @typedef {'fenced'|'indented'} Style
|
||||
* @typedef {'consistent'|Style} Options
|
||||
*/
|
||||
|
||||
import {lintRule} from 'unified-lint-rule'
|
||||
import {visit} from 'unist-util-visit'
|
||||
import {pointStart, pointEnd} from 'unist-util-position'
|
||||
import {generated} from 'unist-util-generated'
|
||||
|
||||
const styles = {null: true, fenced: true, indented: true}
|
||||
|
||||
const remarkLintCodeBlockStyle = lintRule(
|
||||
'remark-lint:code-block-style',
|
||||
codeBlockStyle
|
||||
/** @type {import('unified-lint-rule').Rule<Root, Options>} */
|
||||
(tree, file, option = 'consistent') => {
|
||||
const value = String(file)
|
||||
|
||||
if (
|
||||
option !== 'consistent' &&
|
||||
option !== 'fenced' &&
|
||||
option !== 'indented'
|
||||
) {
|
||||
file.fail(
|
||||
'Incorrect code block style `' +
|
||||
option +
|
||||
"`: use either `'consistent'`, `'fenced'`, or `'indented'`"
|
||||
)
|
||||
}
|
||||
|
||||
visit(tree, 'code', (node) => {
|
||||
if (generated(node)) {
|
||||
return
|
||||
}
|
||||
|
||||
const initial = pointStart(node).offset
|
||||
const final = pointEnd(node).offset
|
||||
|
||||
const current =
|
||||
node.lang || /^\s*([~`])\1{2,}/.test(value.slice(initial, final))
|
||||
? 'fenced'
|
||||
: 'indented'
|
||||
|
||||
if (option === 'consistent') {
|
||||
option = current
|
||||
} else if (option !== current) {
|
||||
file.message('Code blocks should be ' + option, node)
|
||||
}
|
||||
})
|
||||
}
|
||||
)
|
||||
|
||||
export default remarkLintCodeBlockStyle
|
||||
|
||||
function codeBlockStyle(tree, file, option) {
|
||||
const value = String(file)
|
||||
let preferred =
|
||||
typeof option === 'string' && option !== 'consistent' ? option : null
|
||||
|
||||
if (styles[preferred] !== true) {
|
||||
file.fail(
|
||||
'Incorrect code block style `' +
|
||||
preferred +
|
||||
"`: use either `'consistent'`, `'fenced'`, or `'indented'`"
|
||||
)
|
||||
}
|
||||
|
||||
visit(tree, 'code', (node) => {
|
||||
if (generated(node)) {
|
||||
return
|
||||
}
|
||||
|
||||
const initial = pointStart(node).offset
|
||||
const final = pointEnd(node).offset
|
||||
|
||||
const current =
|
||||
node.lang || /^\s*([~`])\1{2,}/.test(value.slice(initial, final))
|
||||
? 'fenced'
|
||||
: 'indented'
|
||||
|
||||
if (preferred) {
|
||||
if (preferred !== current) {
|
||||
file.message('Code blocks should be ' + preferred, node)
|
||||
}
|
||||
} else {
|
||||
preferred = current
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -24,14 +24,27 @@
|
||||
"sideEffects": false,
|
||||
"type": "module",
|
||||
"main": "index.js",
|
||||
"types": "index.d.ts",
|
||||
"files": [
|
||||
"index.d.ts",
|
||||
"index.js"
|
||||
],
|
||||
"dependencies": {
|
||||
"@types/mdast": "^3.0.0",
|
||||
"unified": "^10.0.0",
|
||||
"unified-lint-rule": "^1.0.0",
|
||||
"unist-util-generated": "^2.0.0",
|
||||
"unist-util-position": "^4.0.0",
|
||||
"unist-util-visit": "^4.0.0"
|
||||
},
|
||||
"xo": false
|
||||
"scripts": {
|
||||
"build": "rimraf \"*.d.ts\" && tsc && type-coverage"
|
||||
},
|
||||
"xo": false,
|
||||
"typeCoverage": {
|
||||
"atLeast": 100,
|
||||
"detail": true,
|
||||
"strict": true,
|
||||
"ignoreCatch": true
|
||||
}
|
||||
}
|
||||
|
@ -158,12 +158,18 @@ When configured with `'💩'`.
|
||||
|
||||
## Install
|
||||
|
||||
This package is [ESM only][esm]:
|
||||
Node 12+ is needed to use it and it must be `imported`ed instead of `required`d.
|
||||
|
||||
[npm][]:
|
||||
|
||||
```sh
|
||||
npm install remark-lint-code-block-style
|
||||
```
|
||||
|
||||
This package exports no identifiers.
|
||||
The default export is `remarkLintCodeBlockStyle`.
|
||||
|
||||
## Use
|
||||
|
||||
You probably want to use it on the CLI through a config file:
|
||||
@ -244,6 +250,8 @@ abide by its terms.
|
||||
|
||||
[chat]: https://github.com/remarkjs/remark/discussions
|
||||
|
||||
[esm]: https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c
|
||||
|
||||
[npm]: https://docs.npmjs.com/cli/install
|
||||
|
||||
[health]: https://github.com/remarkjs/.github
|
||||
|
4
packages/remark-lint-code-block-style/tsconfig.json
Normal file
4
packages/remark-lint-code-block-style/tsconfig.json
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"include": ["*.js"]
|
||||
}
|
@ -22,32 +22,36 @@
|
||||
* 1:1-1:47: Do not use uppercase characters in definition labels
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {import('mdast').Root} Root
|
||||
*/
|
||||
|
||||
import {lintRule} from 'unified-lint-rule'
|
||||
import {visit} from 'unist-util-visit'
|
||||
import {pointStart, pointEnd} from 'unist-util-position'
|
||||
import {generated} from 'unist-util-generated'
|
||||
|
||||
const label = /^\s*\[((?:\\[\s\S]|[^[\]])+)]/
|
||||
|
||||
const remarkLintDefinitionCase = lintRule(
|
||||
'remark-lint:definition-case',
|
||||
/** @type {import('unified-lint-rule').Rule<Root, void>} */
|
||||
(tree, file) => {
|
||||
const value = String(file)
|
||||
|
||||
visit(tree, (node) => {
|
||||
if (
|
||||
(node.type === 'definition' || node.type === 'footnoteDefinition') &&
|
||||
!generated(node)
|
||||
) {
|
||||
if (node.type === 'definition' || node.type === 'footnoteDefinition') {
|
||||
const start = pointStart(node).offset
|
||||
const end = pointEnd(node).offset
|
||||
const slice = value.slice(start, end).match(label)[1]
|
||||
|
||||
if (slice !== slice.toLowerCase()) {
|
||||
file.message(
|
||||
'Do not use uppercase characters in definition labels',
|
||||
node
|
||||
)
|
||||
if (typeof start === 'number' && typeof end === 'number') {
|
||||
const match = value.slice(start, end).match(label)
|
||||
|
||||
if (match && match[1] !== match[1].toLowerCase()) {
|
||||
file.message(
|
||||
'Do not use uppercase characters in definition labels',
|
||||
node
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -24,14 +24,26 @@
|
||||
"sideEffects": false,
|
||||
"type": "module",
|
||||
"main": "index.js",
|
||||
"types": "index.d.ts",
|
||||
"files": [
|
||||
"index.d.ts",
|
||||
"index.js"
|
||||
],
|
||||
"dependencies": {
|
||||
"@types/mdast": "^3.0.0",
|
||||
"unified": "^10.0.0",
|
||||
"unified-lint-rule": "^1.0.0",
|
||||
"unist-util-generated": "^2.0.0",
|
||||
"unist-util-position": "^4.0.0",
|
||||
"unist-util-visit": "^4.0.0"
|
||||
},
|
||||
"xo": false
|
||||
"scripts": {
|
||||
"build": "rimraf \"*.d.ts\" && tsc && type-coverage"
|
||||
},
|
||||
"xo": false,
|
||||
"typeCoverage": {
|
||||
"atLeast": 100,
|
||||
"detail": true,
|
||||
"strict": true,
|
||||
"ignoreCatch": true
|
||||
}
|
||||
}
|
||||
|
@ -50,12 +50,18 @@ No messages.
|
||||
|
||||
## Install
|
||||
|
||||
This package is [ESM only][esm]:
|
||||
Node 12+ is needed to use it and it must be `imported`ed instead of `required`d.
|
||||
|
||||
[npm][]:
|
||||
|
||||
```sh
|
||||
npm install remark-lint-definition-case
|
||||
```
|
||||
|
||||
This package exports no identifiers.
|
||||
The default export is `remarkLintDefinitionCase`.
|
||||
|
||||
## Use
|
||||
|
||||
You probably want to use it on the CLI through a config file:
|
||||
@ -136,6 +142,8 @@ abide by its terms.
|
||||
|
||||
[chat]: https://github.com/remarkjs/remark/discussions
|
||||
|
||||
[esm]: https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c
|
||||
|
||||
[npm]: https://docs.npmjs.com/cli/install
|
||||
|
||||
[health]: https://github.com/remarkjs/.github
|
||||
|
4
packages/remark-lint-definition-case/tsconfig.json
Normal file
4
packages/remark-lint-definition-case/tsconfig.json
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"include": ["*.js"]
|
||||
}
|
@ -22,31 +22,36 @@
|
||||
* 1:1-1:57: Do not use consecutive whitespace in definition labels
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {import('mdast').Root} Root
|
||||
*/
|
||||
|
||||
import {lintRule} from 'unified-lint-rule'
|
||||
import {visit} from 'unist-util-visit'
|
||||
import {pointStart, pointEnd} from 'unist-util-position'
|
||||
import {generated} from 'unist-util-generated'
|
||||
|
||||
const label = /^\s*\[((?:\\[\s\S]|[^[\]])+)]/
|
||||
|
||||
const remarkLintDefinitionSpacing = lintRule(
|
||||
'remark-lint:definition-spacing',
|
||||
/** @type {import('unified-lint-rule').Rule<Root, void>} */
|
||||
(tree, file) => {
|
||||
const value = String(file)
|
||||
|
||||
visit(tree, (node) => {
|
||||
if (
|
||||
(node.type === 'definition' || node.type === 'footnoteDefinition') &&
|
||||
!generated(node)
|
||||
) {
|
||||
if (node.type === 'definition' || node.type === 'footnoteDefinition') {
|
||||
const start = pointStart(node).offset
|
||||
const end = pointEnd(node).offset
|
||||
|
||||
if (/[ \t\n]{2,}/.test(value.slice(start, end).match(label)[1])) {
|
||||
file.message(
|
||||
'Do not use consecutive whitespace in definition labels',
|
||||
node
|
||||
)
|
||||
if (typeof start === 'number' && typeof end === 'number') {
|
||||
const match = value.slice(start, end).match(label)
|
||||
|
||||
if (match && /[ \t\n]{2,}/.test(match[1])) {
|
||||
file.message(
|
||||
'Do not use consecutive whitespace in definition labels',
|
||||
node
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -24,14 +24,26 @@
|
||||
"sideEffects": false,
|
||||
"type": "module",
|
||||
"main": "index.js",
|
||||
"types": "index.d.ts",
|
||||
"files": [
|
||||
"index.d.ts",
|
||||
"index.js"
|
||||
],
|
||||
"dependencies": {
|
||||
"@types/mdast": "^3.0.0",
|
||||
"unified": "^10.0.0",
|
||||
"unified-lint-rule": "^1.0.0",
|
||||
"unist-util-generated": "^2.0.0",
|
||||
"unist-util-position": "^4.0.0",
|
||||
"unist-util-visit": "^4.0.0"
|
||||
},
|
||||
"xo": false
|
||||
"scripts": {
|
||||
"build": "rimraf \"*.d.ts\" && tsc && type-coverage"
|
||||
},
|
||||
"xo": false,
|
||||
"typeCoverage": {
|
||||
"atLeast": 100,
|
||||
"detail": true,
|
||||
"strict": true,
|
||||
"ignoreCatch": true
|
||||
}
|
||||
}
|
||||
|
@ -52,12 +52,18 @@ Note: `·` represents a space.
|
||||
|
||||
## Install
|
||||
|
||||
This package is [ESM only][esm]:
|
||||
Node 12+ is needed to use it and it must be `imported`ed instead of `required`d.
|
||||
|
||||
[npm][]:
|
||||
|
||||
```sh
|
||||
npm install remark-lint-definition-spacing
|
||||
```
|
||||
|
||||
This package exports no identifiers.
|
||||
The default export is `remarkLintDefinitionSpacing`.
|
||||
|
||||
## Use
|
||||
|
||||
You probably want to use it on the CLI through a config file:
|
||||
@ -138,6 +144,8 @@ abide by its terms.
|
||||
|
||||
[chat]: https://github.com/remarkjs/remark/discussions
|
||||
|
||||
[esm]: https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c
|
||||
|
||||
[npm]: https://docs.npmjs.com/cli/install
|
||||
|
||||
[health]: https://github.com/remarkjs/.github
|
||||
|
4
packages/remark-lint-definition-spacing/tsconfig.json
Normal file
4
packages/remark-lint-definition-spacing/tsconfig.json
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"include": ["*.js"]
|
||||
}
|
@ -69,41 +69,40 @@
|
||||
* 1:1: Incorrect emphasis marker `💩`: use either `'consistent'`, `'*'`, or `'_'`
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {import('mdast').Root} Root
|
||||
* @typedef {'*'|'_'} Marker
|
||||
* @typedef {'consistent'|Marker} Options
|
||||
*/
|
||||
|
||||
import {lintRule} from 'unified-lint-rule'
|
||||
import {visit} from 'unist-util-visit'
|
||||
import {pointStart} from 'unist-util-position'
|
||||
import {generated} from 'unist-util-generated'
|
||||
|
||||
const markers = {null: true, '*': true, _: true}
|
||||
|
||||
const remarkLintEmphasisMarker = lintRule(
|
||||
'remark-lint:emphasis-marker',
|
||||
(tree, file, option) => {
|
||||
/** @type {import('unified-lint-rule').Rule<Root, Options>} */
|
||||
(tree, file, option = 'consistent') => {
|
||||
const value = String(file)
|
||||
let preferred =
|
||||
typeof option === 'string' && option !== 'consistent' ? option : null
|
||||
|
||||
if (markers[preferred] !== true) {
|
||||
if (option !== '*' && option !== '_' && option !== 'consistent') {
|
||||
file.fail(
|
||||
'Incorrect emphasis marker `' +
|
||||
preferred +
|
||||
option +
|
||||
"`: use either `'consistent'`, `'*'`, or `'_'`"
|
||||
)
|
||||
}
|
||||
|
||||
visit(tree, 'emphasis', (node) => {
|
||||
if (!generated(node)) {
|
||||
const marker = value.charAt(pointStart(node).offset)
|
||||
const start = pointStart(node).offset
|
||||
|
||||
if (preferred) {
|
||||
if (marker !== preferred) {
|
||||
file.message(
|
||||
'Emphasis should use `' + preferred + '` as a marker',
|
||||
node
|
||||
)
|
||||
}
|
||||
} else {
|
||||
preferred = marker
|
||||
if (typeof start === 'number') {
|
||||
const marker = /** @type {Marker} */ (value.charAt(start))
|
||||
|
||||
if (option === 'consistent') {
|
||||
option = marker
|
||||
} else if (marker !== option) {
|
||||
file.message('Emphasis should use `' + option + '` as a marker', node)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -24,14 +24,26 @@
|
||||
"sideEffects": false,
|
||||
"type": "module",
|
||||
"main": "index.js",
|
||||
"types": "index.d.ts",
|
||||
"files": [
|
||||
"index.d.ts",
|
||||
"index.js"
|
||||
],
|
||||
"dependencies": {
|
||||
"@types/mdast": "^3.0.0",
|
||||
"unified": "^10.0.0",
|
||||
"unified-lint-rule": "^1.0.0",
|
||||
"unist-util-generated": "^2.0.0",
|
||||
"unist-util-position": "^4.0.0",
|
||||
"unist-util-visit": "^4.0.0"
|
||||
},
|
||||
"xo": false
|
||||
"scripts": {
|
||||
"build": "rimraf \"*.d.ts\" && tsc && type-coverage"
|
||||
},
|
||||
"xo": false,
|
||||
"typeCoverage": {
|
||||
"atLeast": 100,
|
||||
"detail": true,
|
||||
"strict": true,
|
||||
"ignoreCatch": true
|
||||
}
|
||||
}
|
||||
|
@ -126,12 +126,18 @@ When configured with `'💩'`.
|
||||
|
||||
## Install
|
||||
|
||||
This package is [ESM only][esm]:
|
||||
Node 12+ is needed to use it and it must be `imported`ed instead of `required`d.
|
||||
|
||||
[npm][]:
|
||||
|
||||
```sh
|
||||
npm install remark-lint-emphasis-marker
|
||||
```
|
||||
|
||||
This package exports no identifiers.
|
||||
The default export is `remarkLintEmphasisMarker`.
|
||||
|
||||
## Use
|
||||
|
||||
You probably want to use it on the CLI through a config file:
|
||||
@ -212,6 +218,8 @@ abide by its terms.
|
||||
|
||||
[chat]: https://github.com/remarkjs/remark/discussions
|
||||
|
||||
[esm]: https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c
|
||||
|
||||
[npm]: https://docs.npmjs.com/cli/install
|
||||
|
||||
[health]: https://github.com/remarkjs/.github
|
||||
|
4
packages/remark-lint-emphasis-marker/tsconfig.json
Normal file
4
packages/remark-lint-emphasis-marker/tsconfig.json
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"include": ["*.js"]
|
||||
}
|
@ -61,6 +61,13 @@
|
||||
* ```
|
||||
*
|
||||
* @example
|
||||
* {"name": "ok.md", "setting": {"flags":["alpha"]}}
|
||||
*
|
||||
* ```alpha
|
||||
* bravo()
|
||||
* ```
|
||||
*
|
||||
* @example
|
||||
* {"name": "not-ok.md", "setting": ["charlie"], "label": "input"}
|
||||
*
|
||||
* ```alpha
|
||||
@ -73,6 +80,18 @@
|
||||
* 1:1-3:4: Incorrect code language flag
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {import('mdast').Root} Root
|
||||
*
|
||||
* @typedef {string[]} Flags
|
||||
*
|
||||
* @typedef FlagMap
|
||||
* @property {Flags} [flags]
|
||||
* @property {boolean} [allowEmpty=false]
|
||||
*
|
||||
* @typedef {Flags|FlagMap} Options
|
||||
*/
|
||||
|
||||
import {lintRule} from 'unified-lint-rule'
|
||||
import {visit} from 'unist-util-visit'
|
||||
import {pointStart, pointEnd} from 'unist-util-position'
|
||||
@ -82,19 +101,23 @@ const fence = /^ {0,3}([~`])\1{2,}/
|
||||
|
||||
const remarkLintFencedCodeFlag = lintRule(
|
||||
'remark-lint:fenced-code-flag',
|
||||
/** @type {import('unified-lint-rule').Rule<Root, Options>} */
|
||||
(tree, file, option) => {
|
||||
const value = String(file)
|
||||
let allowEmpty = false
|
||||
/** @type {string[]} */
|
||||
let allowed = []
|
||||
let flags = option
|
||||
|
||||
if (typeof flags === 'object' && !Array.isArray(flags)) {
|
||||
allowEmpty = Boolean(flags.allowEmpty)
|
||||
flags = flags.flags
|
||||
}
|
||||
if (typeof option === 'object') {
|
||||
if (Array.isArray(option)) {
|
||||
allowed = option
|
||||
} else {
|
||||
allowEmpty = Boolean(option.allowEmpty)
|
||||
|
||||
if (Array.isArray(flags)) {
|
||||
allowed = String(flags).split(',')
|
||||
if (option.flags) {
|
||||
allowed = option.flags
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
visit(tree, 'code', (node) => {
|
||||
|
@ -26,14 +26,27 @@
|
||||
"sideEffects": false,
|
||||
"type": "module",
|
||||
"main": "index.js",
|
||||
"types": "index.d.ts",
|
||||
"files": [
|
||||
"index.d.ts",
|
||||
"index.js"
|
||||
],
|
||||
"dependencies": {
|
||||
"@types/mdast": "^3.0.0",
|
||||
"unified": "^10.0.0",
|
||||
"unified-lint-rule": "^1.0.0",
|
||||
"unist-util-generated": "^2.0.0",
|
||||
"unist-util-position": "^4.0.0",
|
||||
"unist-util-visit": "^4.0.0"
|
||||
},
|
||||
"xo": false
|
||||
"scripts": {
|
||||
"build": "rimraf \"*.d.ts\" && tsc && type-coverage"
|
||||
},
|
||||
"xo": false,
|
||||
"typeCoverage": {
|
||||
"atLeast": 100,
|
||||
"detail": true,
|
||||
"strict": true,
|
||||
"ignoreCatch": true
|
||||
}
|
||||
}
|
||||
|
@ -111,6 +111,22 @@ bravo()
|
||||
|
||||
No messages.
|
||||
|
||||
##### `ok.md`
|
||||
|
||||
When configured with `{ flags: [ 'alpha' ] }`.
|
||||
|
||||
###### In
|
||||
|
||||
````markdown
|
||||
```alpha
|
||||
bravo()
|
||||
```
|
||||
````
|
||||
|
||||
###### Out
|
||||
|
||||
No messages.
|
||||
|
||||
##### `not-ok.md`
|
||||
|
||||
When configured with `[ 'charlie' ]`.
|
||||
@ -131,12 +147,18 @@ bravo()
|
||||
|
||||
## Install
|
||||
|
||||
This package is [ESM only][esm]:
|
||||
Node 12+ is needed to use it and it must be `imported`ed instead of `required`d.
|
||||
|
||||
[npm][]:
|
||||
|
||||
```sh
|
||||
npm install remark-lint-fenced-code-flag
|
||||
```
|
||||
|
||||
This package exports no identifiers.
|
||||
The default export is `remarkLintFencedCodeFlag`.
|
||||
|
||||
## Use
|
||||
|
||||
You probably want to use it on the CLI through a config file:
|
||||
@ -217,6 +239,8 @@ abide by its terms.
|
||||
|
||||
[chat]: https://github.com/remarkjs/remark/discussions
|
||||
|
||||
[esm]: https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c
|
||||
|
||||
[npm]: https://docs.npmjs.com/cli/install
|
||||
|
||||
[health]: https://github.com/remarkjs/.github
|
||||
|
4
packages/remark-lint-fenced-code-flag/tsconfig.json
Normal file
4
packages/remark-lint-fenced-code-flag/tsconfig.json
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"include": ["*.js"]
|
||||
}
|
@ -89,53 +89,50 @@
|
||||
* 1:1: Incorrect fenced code marker `💩`: use either `'consistent'`, `` '`' ``, or `'~'`
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {import('mdast').Root} Root
|
||||
* @typedef {'~'|'`'} Marker
|
||||
* @typedef {'consistent'|Marker} Options
|
||||
*/
|
||||
|
||||
import {lintRule} from 'unified-lint-rule'
|
||||
import {visit} from 'unist-util-visit'
|
||||
import {pointStart} from 'unist-util-position'
|
||||
import {generated} from 'unist-util-generated'
|
||||
|
||||
const markers = {
|
||||
'`': true,
|
||||
'~': true,
|
||||
null: true
|
||||
}
|
||||
|
||||
const remarkLintFencedCodeMarker = lintRule(
|
||||
'remark-lint:fenced-code-marker',
|
||||
(tree, file, option) => {
|
||||
/** @type {import('unified-lint-rule').Rule<Root, Options>} */
|
||||
(tree, file, option = 'consistent') => {
|
||||
const contents = String(file)
|
||||
let preferred =
|
||||
typeof option === 'string' && option !== 'consistent' ? option : null
|
||||
|
||||
if (markers[preferred] !== true) {
|
||||
if (option !== 'consistent' && option !== '~' && option !== '`') {
|
||||
file.fail(
|
||||
'Incorrect fenced code marker `' +
|
||||
preferred +
|
||||
option +
|
||||
"`: use either `'consistent'`, `` '`' ``, or `'~'`"
|
||||
)
|
||||
}
|
||||
|
||||
visit(tree, 'code', (node) => {
|
||||
if (!generated(node)) {
|
||||
const start = pointStart(node).offset
|
||||
const start = pointStart(node).offset
|
||||
|
||||
if (typeof start === 'number') {
|
||||
const marker = contents
|
||||
.slice(start, start + 4)
|
||||
.replace(/^\s+/, '')
|
||||
.charAt(0)
|
||||
|
||||
// Ignore unfenced code blocks.
|
||||
if (markers[marker] === true) {
|
||||
if (preferred) {
|
||||
if (marker !== preferred) {
|
||||
file.message(
|
||||
'Fenced code should use `' +
|
||||
(preferred === '~' ? preferred : '` ` `') +
|
||||
'` as a marker',
|
||||
node
|
||||
)
|
||||
}
|
||||
} else {
|
||||
preferred = marker
|
||||
if (marker === '~' || marker === '`') {
|
||||
if (option === 'consistent') {
|
||||
option = marker
|
||||
} else if (marker !== option) {
|
||||
file.message(
|
||||
'Fenced code should use `' +
|
||||
(option === '~' ? option : '` ` `') +
|
||||
'` as a marker',
|
||||
node
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -25,14 +25,26 @@
|
||||
"sideEffects": false,
|
||||
"type": "module",
|
||||
"main": "index.js",
|
||||
"types": "index.d.ts",
|
||||
"files": [
|
||||
"index.d.ts",
|
||||
"index.js"
|
||||
],
|
||||
"dependencies": {
|
||||
"@types/mdast": "^3.0.0",
|
||||
"unified": "^10.0.0",
|
||||
"unified-lint-rule": "^1.0.0",
|
||||
"unist-util-generated": "^2.0.0",
|
||||
"unist-util-position": "^4.0.0",
|
||||
"unist-util-visit": "^4.0.0"
|
||||
},
|
||||
"xo": false
|
||||
"scripts": {
|
||||
"build": "rimraf \"*.d.ts\" && tsc && type-coverage"
|
||||
},
|
||||
"xo": false,
|
||||
"typeCoverage": {
|
||||
"atLeast": 100,
|
||||
"detail": true,
|
||||
"strict": true,
|
||||
"ignoreCatch": true
|
||||
}
|
||||
}
|
||||
|
@ -145,12 +145,18 @@ When configured with `'💩'`.
|
||||
|
||||
## Install
|
||||
|
||||
This package is [ESM only][esm]:
|
||||
Node 12+ is needed to use it and it must be `imported`ed instead of `required`d.
|
||||
|
||||
[npm][]:
|
||||
|
||||
```sh
|
||||
npm install remark-lint-fenced-code-marker
|
||||
```
|
||||
|
||||
This package exports no identifiers.
|
||||
The default export is `remarkLintFencedCodeMarker`.
|
||||
|
||||
## Use
|
||||
|
||||
You probably want to use it on the CLI through a config file:
|
||||
@ -231,6 +237,8 @@ abide by its terms.
|
||||
|
||||
[chat]: https://github.com/remarkjs/remark/discussions
|
||||
|
||||
[esm]: https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c
|
||||
|
||||
[npm]: https://docs.npmjs.com/cli/install
|
||||
|
||||
[health]: https://github.com/remarkjs/.github
|
||||
|
4
packages/remark-lint-fenced-code-marker/tsconfig.json
Normal file
4
packages/remark-lint-fenced-code-marker/tsconfig.json
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"include": ["*.js"]
|
||||
}
|
@ -26,11 +26,17 @@
|
||||
* {"name": "readme.mkd", "setting": "mkd"}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {import('mdast').Root} Root
|
||||
* @typedef {string} Options
|
||||
*/
|
||||
|
||||
import {lintRule} from 'unified-lint-rule'
|
||||
|
||||
const remarkLintFileExtension = lintRule(
|
||||
'remark-lint:file-extension',
|
||||
(tree, file, option) => {
|
||||
/** @type {import('unified-lint-rule').Rule<Root, Options>} */
|
||||
(_, file, option) => {
|
||||
const ext = file.extname
|
||||
const preferred = typeof option === 'string' ? option : 'md'
|
||||
|
||||
|
@ -25,11 +25,24 @@
|
||||
"sideEffects": false,
|
||||
"type": "module",
|
||||
"main": "index.js",
|
||||
"types": "index.d.ts",
|
||||
"files": [
|
||||
"index.d.ts",
|
||||
"index.js"
|
||||
],
|
||||
"dependencies": {
|
||||
"@types/mdast": "^3.0.0",
|
||||
"unified": "^10.0.0",
|
||||
"unified-lint-rule": "^1.0.0"
|
||||
},
|
||||
"xo": false
|
||||
"scripts": {
|
||||
"build": "rimraf \"*.d.ts\" && tsc && type-coverage"
|
||||
},
|
||||
"xo": false,
|
||||
"typeCoverage": {
|
||||
"atLeast": 100,
|
||||
"detail": true,
|
||||
"strict": true,
|
||||
"ignoreCatch": true
|
||||
}
|
||||
}
|
||||
|
@ -57,12 +57,18 @@ No messages.
|
||||
|
||||
## Install
|
||||
|
||||
This package is [ESM only][esm]:
|
||||
Node 12+ is needed to use it and it must be `imported`ed instead of `required`d.
|
||||
|
||||
[npm][]:
|
||||
|
||||
```sh
|
||||
npm install remark-lint-file-extension
|
||||
```
|
||||
|
||||
This package exports no identifiers.
|
||||
The default export is `remarkLintFileExtension`.
|
||||
|
||||
## Use
|
||||
|
||||
You probably want to use it on the CLI through a config file:
|
||||
@ -143,6 +149,8 @@ abide by its terms.
|
||||
|
||||
[chat]: https://github.com/remarkjs/remark/discussions
|
||||
|
||||
[esm]: https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c
|
||||
|
||||
[npm]: https://docs.npmjs.com/cli/install
|
||||
|
||||
[health]: https://github.com/remarkjs/.github
|
||||
|
4
packages/remark-lint-file-extension/tsconfig.json
Normal file
4
packages/remark-lint-file-extension/tsconfig.json
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"include": ["*.js"]
|
||||
}
|
@ -40,6 +40,10 @@
|
||||
* [example-2]: http://example.com/two/
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {import('mdast').Root} Root
|
||||
*/
|
||||
|
||||
import {lintRule} from 'unified-lint-rule'
|
||||
import {visit} from 'unist-util-visit'
|
||||
import {pointStart} from 'unist-util-position'
|
||||
@ -47,8 +51,9 @@ import {generated} from 'unist-util-generated'
|
||||
|
||||
const remarkLintFinalDefinition = lintRule(
|
||||
'remark-lint:final-definition',
|
||||
/** @type {import('unified-lint-rule').Rule<Root, void>} */
|
||||
(tree, file) => {
|
||||
let last = null
|
||||
let last = 0
|
||||
|
||||
visit(
|
||||
tree,
|
||||
@ -65,7 +70,7 @@ const remarkLintFinalDefinition = lintRule(
|
||||
const line = pointStart(node).line
|
||||
|
||||
if (node.type === 'definition') {
|
||||
if (last !== null && last > line) {
|
||||
if (last && last > line) {
|
||||
file.message(
|
||||
'Move definitions to the end of the file (after the node at line `' +
|
||||
last +
|
||||
@ -73,7 +78,7 @@ const remarkLintFinalDefinition = lintRule(
|
||||
node
|
||||
)
|
||||
}
|
||||
} else if (last === null) {
|
||||
} else if (last === 0) {
|
||||
last = line
|
||||
}
|
||||
},
|
||||
|
@ -25,14 +25,27 @@
|
||||
"sideEffects": false,
|
||||
"type": "module",
|
||||
"main": "index.js",
|
||||
"types": "index.d.ts",
|
||||
"files": [
|
||||
"index.d.ts",
|
||||
"index.js"
|
||||
],
|
||||
"dependencies": {
|
||||
"@types/mdast": "^3.0.0",
|
||||
"unified": "^10.0.0",
|
||||
"unified-lint-rule": "^1.0.0",
|
||||
"unist-util-generated": "^2.0.0",
|
||||
"unist-util-position": "^4.0.0",
|
||||
"unist-util-visit": "^4.0.0"
|
||||
},
|
||||
"xo": false
|
||||
"scripts": {
|
||||
"build": "rimraf \"*.d.ts\" && tsc && type-coverage"
|
||||
},
|
||||
"xo": false,
|
||||
"typeCoverage": {
|
||||
"atLeast": 100,
|
||||
"detail": true,
|
||||
"strict": true,
|
||||
"ignoreCatch": true
|
||||
}
|
||||
}
|
||||
|
@ -75,12 +75,18 @@ No messages.
|
||||
|
||||
## Install
|
||||
|
||||
This package is [ESM only][esm]:
|
||||
Node 12+ is needed to use it and it must be `imported`ed instead of `required`d.
|
||||
|
||||
[npm][]:
|
||||
|
||||
```sh
|
||||
npm install remark-lint-final-definition
|
||||
```
|
||||
|
||||
This package exports no identifiers.
|
||||
The default export is `remarkLintFinalDefinition`.
|
||||
|
||||
## Use
|
||||
|
||||
You probably want to use it on the CLI through a config file:
|
||||
@ -161,6 +167,8 @@ abide by its terms.
|
||||
|
||||
[chat]: https://github.com/remarkjs/remark/discussions
|
||||
|
||||
[esm]: https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c
|
||||
|
||||
[npm]: https://docs.npmjs.com/cli/install
|
||||
|
||||
[health]: https://github.com/remarkjs/.github
|
||||
|
4
packages/remark-lint-final-definition/tsconfig.json
Normal file
4
packages/remark-lint-final-definition/tsconfig.json
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"include": ["*.js"]
|
||||
}
|
@ -50,11 +50,16 @@
|
||||
* ```
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {import('mdast').Root} Root
|
||||
*/
|
||||
|
||||
import {lintRule} from 'unified-lint-rule'
|
||||
|
||||
const remarkLintFinalNewline = lintRule(
|
||||
'remark-lint:final-newline',
|
||||
(tree, file) => {
|
||||
/** @type {import('unified-lint-rule').Rule<Root, void>} */
|
||||
(_, file) => {
|
||||
const value = String(file)
|
||||
const last = value.length - 1
|
||||
|
||||
|
@ -25,11 +25,24 @@
|
||||
"sideEffects": false,
|
||||
"type": "module",
|
||||
"main": "index.js",
|
||||
"types": "index.d.ts",
|
||||
"files": [
|
||||
"index.d.ts",
|
||||
"index.js"
|
||||
],
|
||||
"dependencies": {
|
||||
"@types/mdast": "^3.0.0",
|
||||
"unified": "^10.0.0",
|
||||
"unified-lint-rule": "^1.0.0"
|
||||
},
|
||||
"xo": false
|
||||
"scripts": {
|
||||
"build": "rimraf \"*.d.ts\" && tsc && type-coverage"
|
||||
},
|
||||
"xo": false,
|
||||
"typeCoverage": {
|
||||
"atLeast": 100,
|
||||
"detail": true,
|
||||
"strict": true,
|
||||
"ignoreCatch": true
|
||||
}
|
||||
}
|
||||
|
@ -65,12 +65,18 @@ This rule is included in the following presets:
|
||||
|
||||
## Install
|
||||
|
||||
This package is [ESM only][esm]:
|
||||
Node 12+ is needed to use it and it must be `imported`ed instead of `required`d.
|
||||
|
||||
[npm][]:
|
||||
|
||||
```sh
|
||||
npm install remark-lint-final-newline
|
||||
```
|
||||
|
||||
This package exports no identifiers.
|
||||
The default export is `remarkLintFinalNewline`.
|
||||
|
||||
## Use
|
||||
|
||||
You probably want to use it on the CLI through a config file:
|
||||
@ -151,6 +157,8 @@ abide by its terms.
|
||||
|
||||
[chat]: https://github.com/remarkjs/remark/discussions
|
||||
|
||||
[esm]: https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c
|
||||
|
||||
[npm]: https://docs.npmjs.com/cli/install
|
||||
|
||||
[health]: https://github.com/remarkjs/.github
|
||||
|
4
packages/remark-lint-final-newline/tsconfig.json
Normal file
4
packages/remark-lint-final-newline/tsconfig.json
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"include": ["*.js"]
|
||||
}
|
@ -90,6 +90,13 @@
|
||||
* 1:1-1:14: First heading level should be `2`
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {import('mdast').Root} Root
|
||||
* @typedef {import('mdast').HTML} HTML
|
||||
* @typedef {import('mdast').Heading['depth']} Depth
|
||||
* @typedef {Depth} Options
|
||||
*/
|
||||
|
||||
import {lintRule} from 'unified-lint-rule'
|
||||
import {visit, EXIT} from 'unist-util-visit'
|
||||
import {generated} from 'unist-util-generated'
|
||||
@ -98,11 +105,11 @@ const re = /<h([1-6])/
|
||||
|
||||
const remarkLintFirstHeadingLevel = lintRule(
|
||||
'remark-lint:first-heading-level',
|
||||
(tree, file, option) => {
|
||||
const preferred = option && option !== true ? option : 1
|
||||
|
||||
/** @type {import('unified-lint-rule').Rule<Root, Options>} */
|
||||
(tree, file, option = 1) => {
|
||||
visit(tree, (node) => {
|
||||
if (!generated(node)) {
|
||||
/** @type {Depth|undefined} */
|
||||
let rank
|
||||
|
||||
if (node.type === 'heading') {
|
||||
@ -112,11 +119,8 @@ const remarkLintFirstHeadingLevel = lintRule(
|
||||
}
|
||||
|
||||
if (rank !== undefined) {
|
||||
if (rank !== preferred) {
|
||||
file.message(
|
||||
'First heading level should be `' + preferred + '`',
|
||||
node
|
||||
)
|
||||
if (rank !== option) {
|
||||
file.message('First heading level should be `' + option + '`', node)
|
||||
}
|
||||
|
||||
return EXIT
|
||||
@ -128,7 +132,12 @@ const remarkLintFirstHeadingLevel = lintRule(
|
||||
|
||||
export default remarkLintFirstHeadingLevel
|
||||
|
||||
/**
|
||||
* @param {HTML} node
|
||||
* @returns {Depth|undefined}
|
||||
*/
|
||||
function infer(node) {
|
||||
const results = node.value.match(re)
|
||||
// @ts-expect-error: can be castes fine.
|
||||
return results ? Number(results[1]) : undefined
|
||||
}
|
||||
|
@ -26,13 +26,26 @@
|
||||
"sideEffects": false,
|
||||
"type": "module",
|
||||
"main": "index.js",
|
||||
"types": "index.d.ts",
|
||||
"files": [
|
||||
"index.d.ts",
|
||||
"index.js"
|
||||
],
|
||||
"dependencies": {
|
||||
"@types/mdast": "^3.0.0",
|
||||
"unified": "^10.0.0",
|
||||
"unified-lint-rule": "^1.0.0",
|
||||
"unist-util-generated": "^2.0.0",
|
||||
"unist-util-visit": "^4.0.0"
|
||||
},
|
||||
"xo": false
|
||||
"scripts": {
|
||||
"build": "rimraf \"*.d.ts\" && tsc && type-coverage"
|
||||
},
|
||||
"xo": false,
|
||||
"typeCoverage": {
|
||||
"atLeast": 100,
|
||||
"detail": true,
|
||||
"strict": true,
|
||||
"ignoreCatch": true
|
||||
}
|
||||
}
|
||||
|
@ -162,12 +162,18 @@ Paragraph.
|
||||
|
||||
## Install
|
||||
|
||||
This package is [ESM only][esm]:
|
||||
Node 12+ is needed to use it and it must be `imported`ed instead of `required`d.
|
||||
|
||||
[npm][]:
|
||||
|
||||
```sh
|
||||
npm install remark-lint-first-heading-level
|
||||
```
|
||||
|
||||
This package exports no identifiers.
|
||||
The default export is `remarkLintFirstHeadingLevel`.
|
||||
|
||||
## Use
|
||||
|
||||
You probably want to use it on the CLI through a config file:
|
||||
@ -248,6 +254,8 @@ abide by its terms.
|
||||
|
||||
[chat]: https://github.com/remarkjs/remark/discussions
|
||||
|
||||
[esm]: https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c
|
||||
|
||||
[npm]: https://docs.npmjs.com/cli/install
|
||||
|
||||
[health]: https://github.com/remarkjs/.github
|
||||
|
4
packages/remark-lint-first-heading-level/tsconfig.json
Normal file
4
packages/remark-lint-first-heading-level/tsconfig.json
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"include": ["*.js"]
|
||||
}
|
@ -24,6 +24,10 @@
|
||||
* 1:12-2:1: Use two spaces for hard line breaks
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {import('mdast').Root} Root
|
||||
*/
|
||||
|
||||
import {lintRule} from 'unified-lint-rule'
|
||||
import {visit} from 'unist-util-visit'
|
||||
import {pointStart, pointEnd} from 'unist-util-position'
|
||||
@ -31,6 +35,7 @@ import {generated} from 'unist-util-generated'
|
||||
|
||||
const remarkLintHardBreakSpaces = lintRule(
|
||||
'remark-lint:hard-break-spaces',
|
||||
/** @type {import('unified-lint-rule').Rule<Root, void>} */
|
||||
(tree, file) => {
|
||||
const value = String(file)
|
||||
|
||||
|
@ -26,14 +26,27 @@
|
||||
"sideEffects": false,
|
||||
"type": "module",
|
||||
"main": "index.js",
|
||||
"types": "index.d.ts",
|
||||
"files": [
|
||||
"index.d.ts",
|
||||
"index.js"
|
||||
],
|
||||
"dependencies": {
|
||||
"@types/mdast": "^3.0.0",
|
||||
"unified": "^10.0.0",
|
||||
"unified-lint-rule": "^1.0.0",
|
||||
"unist-util-generated": "^2.0.0",
|
||||
"unist-util-position": "^4.0.0",
|
||||
"unist-util-visit": "^4.0.0"
|
||||
},
|
||||
"xo": false
|
||||
"scripts": {
|
||||
"build": "rimraf \"*.d.ts\" && tsc && type-coverage"
|
||||
},
|
||||
"xo": false,
|
||||
"typeCoverage": {
|
||||
"atLeast": 100,
|
||||
"detail": true,
|
||||
"strict": true,
|
||||
"ignoreCatch": true
|
||||
}
|
||||
}
|
||||
|
@ -57,12 +57,18 @@ dolor sit amet.
|
||||
|
||||
## Install
|
||||
|
||||
This package is [ESM only][esm]:
|
||||
Node 12+ is needed to use it and it must be `imported`ed instead of `required`d.
|
||||
|
||||
[npm][]:
|
||||
|
||||
```sh
|
||||
npm install remark-lint-hard-break-spaces
|
||||
```
|
||||
|
||||
This package exports no identifiers.
|
||||
The default export is `remarkLintHardBreakSpaces`.
|
||||
|
||||
## Use
|
||||
|
||||
You probably want to use it on the CLI through a config file:
|
||||
@ -143,6 +149,8 @@ abide by its terms.
|
||||
|
||||
[chat]: https://github.com/remarkjs/remark/discussions
|
||||
|
||||
[esm]: https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c
|
||||
|
||||
[npm]: https://docs.npmjs.com/cli/install
|
||||
|
||||
[health]: https://github.com/remarkjs/.github
|
||||
|
4
packages/remark-lint-hard-break-spaces/tsconfig.json
Normal file
4
packages/remark-lint-hard-break-spaces/tsconfig.json
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"include": ["*.js"]
|
||||
}
|
@ -26,13 +26,20 @@
|
||||
* 3:1-3:10: Heading levels should increment by one level at a time
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {import('mdast').Root} Root
|
||||
* @typedef {import('mdast').Heading['depth']} Depth
|
||||
*/
|
||||
|
||||
import {lintRule} from 'unified-lint-rule'
|
||||
import {visit} from 'unist-util-visit'
|
||||
import {generated} from 'unist-util-generated'
|
||||
|
||||
const remarkLintHeadingIncrement = lintRule(
|
||||
'remark-lint:heading-increment',
|
||||
/** @type {import('unified-lint-rule').Rule<Root, void>} */
|
||||
(tree, file) => {
|
||||
/** @type {Depth} */
|
||||
let previous
|
||||
|
||||
visit(tree, 'heading', (node) => {
|
||||
|
@ -25,13 +25,26 @@
|
||||
"sideEffects": false,
|
||||
"type": "module",
|
||||
"main": "index.js",
|
||||
"types": "index.d.ts",
|
||||
"files": [
|
||||
"index.d.ts",
|
||||
"index.js"
|
||||
],
|
||||
"dependencies": {
|
||||
"@types/mdast": "^3.0.0",
|
||||
"unified": "^10.0.0",
|
||||
"unified-lint-rule": "^1.0.0",
|
||||
"unist-util-generated": "^2.0.0",
|
||||
"unist-util-visit": "^4.0.0"
|
||||
},
|
||||
"xo": false
|
||||
"scripts": {
|
||||
"build": "rimraf \"*.d.ts\" && tsc && type-coverage"
|
||||
},
|
||||
"xo": false,
|
||||
"typeCoverage": {
|
||||
"atLeast": 100,
|
||||
"detail": true,
|
||||
"strict": true,
|
||||
"ignoreCatch": true
|
||||
}
|
||||
}
|
||||
|
@ -54,12 +54,18 @@ No messages.
|
||||
|
||||
## Install
|
||||
|
||||
This package is [ESM only][esm]:
|
||||
Node 12+ is needed to use it and it must be `imported`ed instead of `required`d.
|
||||
|
||||
[npm][]:
|
||||
|
||||
```sh
|
||||
npm install remark-lint-heading-increment
|
||||
```
|
||||
|
||||
This package exports no identifiers.
|
||||
The default export is `remarkLintHeadingIncrement`.
|
||||
|
||||
## Use
|
||||
|
||||
You probably want to use it on the CLI through a config file:
|
||||
@ -140,6 +146,8 @@ abide by its terms.
|
||||
|
||||
[chat]: https://github.com/remarkjs/remark/discussions
|
||||
|
||||
[esm]: https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c
|
||||
|
||||
[npm]: https://docs.npmjs.com/cli/install
|
||||
|
||||
[health]: https://github.com/remarkjs/.github
|
||||
|
4
packages/remark-lint-heading-increment/tsconfig.json
Normal file
4
packages/remark-lint-heading-increment/tsconfig.json
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"include": ["*.js"]
|
||||
}
|
@ -69,6 +69,17 @@
|
||||
*
|
||||
* 4:1-4:8: Headings should use setext
|
||||
* 6:1-6:13: Headings should use setext
|
||||
*
|
||||
* @example
|
||||
* {"name": "not-ok.md", "setting": "💩", "label": "output", "positionless": true}
|
||||
*
|
||||
* 1:1: Incorrect heading style type `💩`: use either `'consistent'`, `'atx'`, `'atx-closed'`, or `'setext'`
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {import('mdast').Root} Root
|
||||
* @typedef {'atx'|'atx-closed'|'setext'} Type
|
||||
* @typedef {'consistent'|Type} Options
|
||||
*/
|
||||
|
||||
import {lintRule} from 'unified-lint-rule'
|
||||
@ -76,21 +87,31 @@ import {visit} from 'unist-util-visit'
|
||||
import {headingStyle} from 'mdast-util-heading-style'
|
||||
import {generated} from 'unist-util-generated'
|
||||
|
||||
const types = new Set(['atx', 'atx-closed', 'setext'])
|
||||
|
||||
const remarkLintHeadingStyle = lintRule(
|
||||
'remark-lint:heading-style',
|
||||
(tree, file, option) => {
|
||||
let preferred = types.has(option) ? option : null
|
||||
/** @type {import('unified-lint-rule').Rule<Root, Options>} */
|
||||
(tree, file, option = 'consistent') => {
|
||||
if (
|
||||
option !== 'consistent' &&
|
||||
option !== 'atx' &&
|
||||
option !== 'atx-closed' &&
|
||||
option !== 'setext'
|
||||
) {
|
||||
file.fail(
|
||||
'Incorrect heading style type `' +
|
||||
option +
|
||||
"`: use either `'consistent'`, `'atx'`, `'atx-closed'`, or `'setext'`"
|
||||
)
|
||||
}
|
||||
|
||||
visit(tree, 'heading', (node) => {
|
||||
if (!generated(node)) {
|
||||
if (preferred) {
|
||||
if (headingStyle(node, preferred) !== preferred) {
|
||||
file.message('Headings should use ' + preferred, node)
|
||||
}
|
||||
} else {
|
||||
preferred = headingStyle(node, preferred)
|
||||
if (option === 'consistent') {
|
||||
// Funky nodes perhaps cannot be detected.
|
||||
/* c8 ignore next */
|
||||
option = headingStyle(node) || 'consistent'
|
||||
} else if (headingStyle(node, option) !== option) {
|
||||
file.message('Headings should use ' + option, node)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -26,14 +26,27 @@
|
||||
"sideEffects": false,
|
||||
"type": "module",
|
||||
"main": "index.js",
|
||||
"types": "index.d.ts",
|
||||
"files": [
|
||||
"index.d.ts",
|
||||
"index.js"
|
||||
],
|
||||
"dependencies": {
|
||||
"@types/mdast": "^3.0.0",
|
||||
"mdast-util-heading-style": "^2.0.0",
|
||||
"unified": "^10.0.0",
|
||||
"unified-lint-rule": "^1.0.0",
|
||||
"unist-util-generated": "^2.0.0",
|
||||
"unist-util-visit": "^4.0.0"
|
||||
},
|
||||
"xo": false
|
||||
"scripts": {
|
||||
"build": "rimraf \"*.d.ts\" && tsc && type-coverage"
|
||||
},
|
||||
"xo": false,
|
||||
"typeCoverage": {
|
||||
"atLeast": 100,
|
||||
"detail": true,
|
||||
"strict": true,
|
||||
"ignoreCatch": true
|
||||
}
|
||||
}
|
||||
|
@ -118,14 +118,30 @@ Juliett
|
||||
6:1-6:13: Headings should use setext
|
||||
```
|
||||
|
||||
##### `not-ok.md`
|
||||
|
||||
When configured with `'💩'`.
|
||||
|
||||
###### Out
|
||||
|
||||
```text
|
||||
1:1: Incorrect heading style type `💩`: use either `'consistent'`, `'atx'`, `'atx-closed'`, or `'setext'`
|
||||
```
|
||||
|
||||
## Install
|
||||
|
||||
This package is [ESM only][esm]:
|
||||
Node 12+ is needed to use it and it must be `imported`ed instead of `required`d.
|
||||
|
||||
[npm][]:
|
||||
|
||||
```sh
|
||||
npm install remark-lint-heading-style
|
||||
```
|
||||
|
||||
This package exports no identifiers.
|
||||
The default export is `remarkLintHeadingStyle`.
|
||||
|
||||
## Use
|
||||
|
||||
You probably want to use it on the CLI through a config file:
|
||||
@ -206,6 +222,8 @@ abide by its terms.
|
||||
|
||||
[chat]: https://github.com/remarkjs/remark/discussions
|
||||
|
||||
[esm]: https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c
|
||||
|
||||
[npm]: https://docs.npmjs.com/cli/install
|
||||
|
||||
[health]: https://github.com/remarkjs/.github
|
||||
|
4
packages/remark-lint-heading-style/tsconfig.json
Normal file
4
packages/remark-lint-heading-style/tsconfig.json
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"include": ["*.js"]
|
||||
}
|
@ -51,41 +51,43 @@
|
||||
* 1:6: Expected linebreaks to be windows (`\r\n`), not unix (`\n`)
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {import('mdast').Root} Root
|
||||
* @typedef {'unix'|'windows'} Type
|
||||
* @typedef {'consistent'|Type} Options
|
||||
*/
|
||||
|
||||
import {lintRule} from 'unified-lint-rule'
|
||||
import {location} from 'vfile-location'
|
||||
|
||||
const escaped = {unix: '\\n', windows: '\\r\\n'}
|
||||
const types = {true: 'windows', false: 'unix'}
|
||||
|
||||
const remarkLintLinebreakStyle = lintRule(
|
||||
'remark-lint:linebreak-style',
|
||||
(tree, file, option) => {
|
||||
/** @type {import('unified-lint-rule').Rule<Root, Options>} */
|
||||
(_, file, option = 'consistent') => {
|
||||
const value = String(file)
|
||||
const toPoint = location(value).toPoint
|
||||
let preferred =
|
||||
typeof option === 'string' && option !== 'consistent' ? option : null
|
||||
let index = value.indexOf('\n')
|
||||
|
||||
while (index !== -1) {
|
||||
const type = types[value.charAt(index - 1) === '\r']
|
||||
const type = value.charAt(index - 1) === '\r' ? 'windows' : 'unix'
|
||||
|
||||
if (preferred) {
|
||||
if (preferred !== type) {
|
||||
file.message(
|
||||
'Expected linebreaks to be ' +
|
||||
preferred +
|
||||
' (`' +
|
||||
escaped[preferred] +
|
||||
'`), not ' +
|
||||
type +
|
||||
' (`' +
|
||||
escaped[type] +
|
||||
'`)',
|
||||
toPoint(index)
|
||||
)
|
||||
}
|
||||
} else {
|
||||
preferred = type
|
||||
if (option === 'consistent') {
|
||||
option = type
|
||||
} else if (option !== type) {
|
||||
file.message(
|
||||
'Expected linebreaks to be ' +
|
||||
option +
|
||||
' (`' +
|
||||
escaped[option] +
|
||||
'`), not ' +
|
||||
type +
|
||||
' (`' +
|
||||
escaped[type] +
|
||||
'`)',
|
||||
toPoint(index)
|
||||
)
|
||||
}
|
||||
|
||||
index = value.indexOf('\n', index + 1)
|
||||
|
@ -29,12 +29,25 @@
|
||||
"sideEffects": false,
|
||||
"type": "module",
|
||||
"main": "index.js",
|
||||
"types": "index.d.ts",
|
||||
"files": [
|
||||
"index.d.ts",
|
||||
"index.js"
|
||||
],
|
||||
"dependencies": {
|
||||
"@types/mdast": "^3.0.0",
|
||||
"unified": "^10.0.0",
|
||||
"unified-lint-rule": "^1.0.0",
|
||||
"vfile-location": "^4.0.0"
|
||||
},
|
||||
"xo": false
|
||||
"scripts": {
|
||||
"build": "rimraf \"*.d.ts\" && tsc && type-coverage"
|
||||
},
|
||||
"xo": false,
|
||||
"typeCoverage": {
|
||||
"atLeast": 100,
|
||||
"detail": true,
|
||||
"strict": true,
|
||||
"ignoreCatch": true
|
||||
}
|
||||
}
|
||||
|
@ -98,12 +98,18 @@ Alpha␊
|
||||
|
||||
## Install
|
||||
|
||||
This package is [ESM only][esm]:
|
||||
Node 12+ is needed to use it and it must be `imported`ed instead of `required`d.
|
||||
|
||||
[npm][]:
|
||||
|
||||
```sh
|
||||
npm install remark-lint-linebreak-style
|
||||
```
|
||||
|
||||
This package exports no identifiers.
|
||||
The default export is `remarkLintLinebreakStyle`.
|
||||
|
||||
## Use
|
||||
|
||||
You probably want to use it on the CLI through a config file:
|
||||
@ -184,6 +190,8 @@ abide by its terms.
|
||||
|
||||
[chat]: https://github.com/remarkjs/remark/discussions
|
||||
|
||||
[esm]: https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c
|
||||
|
||||
[npm]: https://docs.npmjs.com/cli/install
|
||||
|
||||
[health]: https://github.com/remarkjs/.github
|
||||
|
4
packages/remark-lint-linebreak-style/tsconfig.json
Normal file
4
packages/remark-lint-linebreak-style/tsconfig.json
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"include": ["*.js"]
|
||||
}
|
@ -98,11 +98,16 @@
|
||||
* 1:1: Incorrect link title style marker `💩`: use either `'consistent'`, `'"'`, `'\''`, or `'()'`
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {import('mdast').Root} Root
|
||||
* @typedef {'"'|"'"|'()'} Marker
|
||||
* @typedef {'consistent'|Marker} Options
|
||||
*/
|
||||
|
||||
import {lintRule} from 'unified-lint-rule'
|
||||
import {location} from 'vfile-location'
|
||||
import {visit} from 'unist-util-visit'
|
||||
import {pointStart, pointEnd} from 'unist-util-position'
|
||||
import {generated} from 'unist-util-generated'
|
||||
|
||||
const own = {}.hasOwnProperty
|
||||
|
||||
@ -114,42 +119,48 @@ const markers = {
|
||||
|
||||
const remarkLintLinkTitleStyle = lintRule(
|
||||
'remark-lint:link-title-style',
|
||||
(tree, file, option) => {
|
||||
/** @type {import('unified-lint-rule').Rule<Root, Options>} */
|
||||
(tree, file, option = 'consistent') => {
|
||||
const value = String(file)
|
||||
const loc = location(file)
|
||||
let preferred =
|
||||
typeof option === 'string' && option !== 'consistent' ? option : null
|
||||
// @ts-expect-error: allow other paren combos.
|
||||
let look = option === '()' || option === '(' ? ')' : option
|
||||
|
||||
if (preferred === '()' || preferred === '(') {
|
||||
preferred = ')'
|
||||
}
|
||||
|
||||
if (preferred && !own.call(markers, preferred)) {
|
||||
if (look !== 'consistent' && !own.call(markers, look)) {
|
||||
file.fail(
|
||||
'Incorrect link title style marker `' +
|
||||
preferred +
|
||||
look +
|
||||
"`: use either `'consistent'`, `'\"'`, `'\\''`, or `'()'`"
|
||||
)
|
||||
}
|
||||
|
||||
visit(tree, (node) => {
|
||||
if (
|
||||
(node.type === 'link' ||
|
||||
node.type === 'image' ||
|
||||
node.type === 'definition') &&
|
||||
!generated(node)
|
||||
node.type === 'link' ||
|
||||
node.type === 'image' ||
|
||||
node.type === 'definition'
|
||||
) {
|
||||
const tail = node.children
|
||||
? node.children[node.children.length - 1]
|
||||
: null
|
||||
const tail =
|
||||
'children' in node
|
||||
? node.children[node.children.length - 1]
|
||||
: undefined
|
||||
const begin = tail ? pointEnd(tail) : pointStart(node)
|
||||
let last = pointEnd(node).offset - 1
|
||||
const end = pointEnd(node)
|
||||
|
||||
if (
|
||||
typeof begin.offset !== 'number' ||
|
||||
typeof end.offset !== 'number'
|
||||
) {
|
||||
return
|
||||
}
|
||||
|
||||
let last = end.offset - 1
|
||||
|
||||
if (node.type !== 'definition') {
|
||||
last--
|
||||
}
|
||||
|
||||
const final = value.charAt(last)
|
||||
const final = /** @type {keyof markers} */ (value.charAt(last))
|
||||
|
||||
// Exit if the final marker is not a known marker.
|
||||
if (!(final in markers)) {
|
||||
@ -163,24 +174,22 @@ const remarkLintLinkTitleStyle = lintRule(
|
||||
|
||||
// Exit if there’s no starting delimiter, the starting delimiter is before
|
||||
// the start of the node, or if it’s not preceded by whitespace.
|
||||
if (first <= begin || !/\s/.test(value.charAt(first - 1))) {
|
||||
if (first <= begin.offset || !/\s/.test(value.charAt(first - 1))) {
|
||||
return
|
||||
}
|
||||
|
||||
if (preferred) {
|
||||
if (preferred !== final) {
|
||||
file.message(
|
||||
'Titles should use `' +
|
||||
(preferred === ')' ? '()' : preferred) +
|
||||
'` as a quote',
|
||||
{
|
||||
start: loc.toPoint(first),
|
||||
end: loc.toPoint(last + 1)
|
||||
}
|
||||
)
|
||||
}
|
||||
} else {
|
||||
preferred = final
|
||||
if (look === 'consistent') {
|
||||
look = final
|
||||
} else if (look !== final) {
|
||||
file.message(
|
||||
'Titles should use `' +
|
||||
(look === ')' ? '()' : look) +
|
||||
'` as a quote',
|
||||
{
|
||||
start: loc.toPoint(first),
|
||||
end: loc.toPoint(last + 1)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -26,15 +26,27 @@
|
||||
"sideEffects": false,
|
||||
"type": "module",
|
||||
"main": "index.js",
|
||||
"types": "index.d.ts",
|
||||
"files": [
|
||||
"index.d.ts",
|
||||
"index.js"
|
||||
],
|
||||
"dependencies": {
|
||||
"@types/mdast": "^3.0.0",
|
||||
"unified": "^10.0.0",
|
||||
"unified-lint-rule": "^1.0.0",
|
||||
"unist-util-generated": "^2.0.0",
|
||||
"unist-util-position": "^4.0.0",
|
||||
"unist-util-visit": "^4.0.0",
|
||||
"vfile-location": "^4.0.0"
|
||||
},
|
||||
"xo": false
|
||||
"scripts": {
|
||||
"build": "rimraf \"*.d.ts\" && tsc && type-coverage"
|
||||
},
|
||||
"xo": false,
|
||||
"typeCoverage": {
|
||||
"atLeast": 100,
|
||||
"detail": true,
|
||||
"strict": true,
|
||||
"ignoreCatch": true
|
||||
}
|
||||
}
|
||||
|
@ -170,12 +170,18 @@ When configured with `'💩'`.
|
||||
|
||||
## Install
|
||||
|
||||
This package is [ESM only][esm]:
|
||||
Node 12+ is needed to use it and it must be `imported`ed instead of `required`d.
|
||||
|
||||
[npm][]:
|
||||
|
||||
```sh
|
||||
npm install remark-lint-link-title-style
|
||||
```
|
||||
|
||||
This package exports no identifiers.
|
||||
The default export is `remarkLintLinkTitleStyle`.
|
||||
|
||||
## Use
|
||||
|
||||
You probably want to use it on the CLI through a config file:
|
||||
@ -256,6 +262,8 @@ abide by its terms.
|
||||
|
||||
[chat]: https://github.com/remarkjs/remark/discussions
|
||||
|
||||
[esm]: https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c
|
||||
|
||||
[npm]: https://docs.npmjs.com/cli/install
|
||||
|
||||
[health]: https://github.com/remarkjs/.github
|
||||
|
4
packages/remark-lint-link-title-style/tsconfig.json
Normal file
4
packages/remark-lint-link-title-style/tsconfig.json
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"include": ["*.js"]
|
||||
}
|
@ -37,13 +37,17 @@
|
||||
* 4:2: Incorrect indentation before bullet: remove 1 space
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {import('mdast').Root} Root
|
||||
*/
|
||||
|
||||
import {lintRule} from 'unified-lint-rule'
|
||||
import plural from 'pluralize'
|
||||
import {visit} from 'unist-util-visit'
|
||||
import {generated} from 'unist-util-generated'
|
||||
|
||||
const remarkLintListItemBulletIndent = lintRule(
|
||||
'remark-lint:list-item-bullet-indent',
|
||||
/** @type {import('unified-lint-rule').Rule<Root, void>} */
|
||||
(tree, file) => {
|
||||
visit(tree, 'list', (list, _, grandparent) => {
|
||||
let index = -1
|
||||
@ -54,8 +58,10 @@ const remarkLintListItemBulletIndent = lintRule(
|
||||
if (
|
||||
grandparent &&
|
||||
grandparent.type === 'root' &&
|
||||
!generated(item) &&
|
||||
!generated(grandparent)
|
||||
grandparent.position &&
|
||||
typeof grandparent.position.start.column === 'number' &&
|
||||
item.position &&
|
||||
typeof item.position.start.column === 'number'
|
||||
) {
|
||||
const indent =
|
||||
item.position.start.column - grandparent.position.start.column
|
||||
|
@ -25,14 +25,26 @@
|
||||
"sideEffects": false,
|
||||
"type": "module",
|
||||
"main": "index.js",
|
||||
"types": "index.d.ts",
|
||||
"files": [
|
||||
"index.d.ts",
|
||||
"index.js"
|
||||
],
|
||||
"dependencies": {
|
||||
"@types/mdast": "^3.0.0",
|
||||
"pluralize": "^8.0.0",
|
||||
"unified": "^10.0.0",
|
||||
"unified-lint-rule": "^1.0.0",
|
||||
"unist-util-generated": "^2.0.0",
|
||||
"unist-util-visit": "^4.0.0"
|
||||
},
|
||||
"xo": false
|
||||
"scripts": {
|
||||
"build": "rimraf \"*.d.ts\" && tsc && type-coverage"
|
||||
},
|
||||
"xo": false,
|
||||
"typeCoverage": {
|
||||
"atLeast": 100,
|
||||
"detail": true,
|
||||
"strict": true,
|
||||
"ignoreCatch": true
|
||||
}
|
||||
}
|
||||
|
@ -67,12 +67,18 @@ Paragraph.
|
||||
|
||||
## Install
|
||||
|
||||
This package is [ESM only][esm]:
|
||||
Node 12+ is needed to use it and it must be `imported`ed instead of `required`d.
|
||||
|
||||
[npm][]:
|
||||
|
||||
```sh
|
||||
npm install remark-lint-list-item-bullet-indent
|
||||
```
|
||||
|
||||
This package exports no identifiers.
|
||||
The default export is `remarkLintListItemBulletIndent`.
|
||||
|
||||
## Use
|
||||
|
||||
You probably want to use it on the CLI through a config file:
|
||||
@ -153,6 +159,8 @@ abide by its terms.
|
||||
|
||||
[chat]: https://github.com/remarkjs/remark/discussions
|
||||
|
||||
[esm]: https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c
|
||||
|
||||
[npm]: https://docs.npmjs.com/cli/install
|
||||
|
||||
[health]: https://github.com/remarkjs/.github
|
||||
|
@ -0,0 +1,4 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"include": ["*.js"]
|
||||
}
|
@ -24,31 +24,38 @@
|
||||
* 2:5: Don’t use mixed indentation for children, remove 1 space
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {import('mdast').Root} Root
|
||||
*/
|
||||
|
||||
import {lintRule} from 'unified-lint-rule'
|
||||
import plural from 'pluralize'
|
||||
import {visit} from 'unist-util-visit'
|
||||
import {pointStart} from 'unist-util-position'
|
||||
import {generated} from 'unist-util-generated'
|
||||
|
||||
const remarkLintListItemContentIndent = lintRule(
|
||||
'remark-lint:list-item-content-indent',
|
||||
/** @type {import('unified-lint-rule').Rule<Root, void>} */
|
||||
(tree, file) => {
|
||||
const value = String(file)
|
||||
|
||||
visit(tree, 'listItem', (node) => {
|
||||
let index = -1
|
||||
/** @type {number|undefined} */
|
||||
let style
|
||||
|
||||
while (++index < node.children.length) {
|
||||
const item = node.children[index]
|
||||
|
||||
if (generated(item)) {
|
||||
continue
|
||||
}
|
||||
|
||||
const begin = pointStart(item)
|
||||
let column = begin.column
|
||||
|
||||
if (
|
||||
typeof begin.column !== 'number' ||
|
||||
typeof begin.offset !== 'number'
|
||||
) {
|
||||
continue
|
||||
}
|
||||
|
||||
// Get indentation for the first child. Only the first item can have a
|
||||
// checkbox, so here we remove that from the column.
|
||||
if (index === 0) {
|
||||
@ -70,7 +77,7 @@ const remarkLintListItemContentIndent = lintRule(
|
||||
}
|
||||
|
||||
// Warn for violating children.
|
||||
if (column !== style) {
|
||||
if (style && column !== style) {
|
||||
const diff = style - column
|
||||
const abs = Math.abs(diff)
|
||||
|
||||
|
@ -26,15 +26,27 @@
|
||||
"sideEffects": false,
|
||||
"type": "module",
|
||||
"main": "index.js",
|
||||
"types": "index.d.ts",
|
||||
"files": [
|
||||
"index.d.ts",
|
||||
"index.js"
|
||||
],
|
||||
"dependencies": {
|
||||
"@types/mdast": "^3.0.0",
|
||||
"pluralize": "^8.0.0",
|
||||
"unified": "^10.0.0",
|
||||
"unified-lint-rule": "^1.0.0",
|
||||
"unist-util-generated": "^2.0.0",
|
||||
"unist-util-position": "^4.0.0",
|
||||
"unist-util-visit": "^4.0.0"
|
||||
},
|
||||
"xo": false
|
||||
"scripts": {
|
||||
"build": "rimraf \"*.d.ts\" && tsc && type-coverage"
|
||||
},
|
||||
"xo": false,
|
||||
"typeCoverage": {
|
||||
"atLeast": 100,
|
||||
"detail": true,
|
||||
"strict": true,
|
||||
"ignoreCatch": true
|
||||
}
|
||||
}
|
||||
|
@ -61,12 +61,18 @@ Note: `·` represents a space.
|
||||
|
||||
## Install
|
||||
|
||||
This package is [ESM only][esm]:
|
||||
Node 12+ is needed to use it and it must be `imported`ed instead of `required`d.
|
||||
|
||||
[npm][]:
|
||||
|
||||
```sh
|
||||
npm install remark-lint-list-item-content-indent
|
||||
```
|
||||
|
||||
This package exports no identifiers.
|
||||
The default export is `remarkLintListItemContentIndent`.
|
||||
|
||||
## Use
|
||||
|
||||
You probably want to use it on the CLI through a config file:
|
||||
@ -147,6 +153,8 @@ abide by its terms.
|
||||
|
||||
[chat]: https://github.com/remarkjs/remark/discussions
|
||||
|
||||
[esm]: https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c
|
||||
|
||||
[npm]: https://docs.npmjs.com/cli/install
|
||||
|
||||
[health]: https://github.com/remarkjs/.github
|
||||
|
@ -0,0 +1,4 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"include": ["*.js"]
|
||||
}
|
@ -113,24 +113,27 @@
|
||||
* 1:1: Incorrect list-item indent style `💩`: use either `'tab-size'`, `'space'`, or `'mixed'`
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {import('mdast').Root} Root
|
||||
* @typedef {'tab-size'|'space'|'mixed'} Options
|
||||
*/
|
||||
|
||||
import {lintRule} from 'unified-lint-rule'
|
||||
import plural from 'pluralize'
|
||||
import {visit} from 'unist-util-visit'
|
||||
import {pointStart} from 'unist-util-position'
|
||||
import {generated} from 'unist-util-generated'
|
||||
|
||||
const styles = {'tab-size': true, mixed: true, space: true}
|
||||
|
||||
const remarkLintListItemIndent = lintRule(
|
||||
'remark-lint:list-item-indent',
|
||||
(tree, file, option) => {
|
||||
const preferred = typeof option === 'string' ? option : 'tab-size'
|
||||
/** @type {import('unified-lint-rule').Rule<Root, Options>} */
|
||||
(tree, file, option = 'tab-size') => {
|
||||
const value = String(file)
|
||||
|
||||
if (styles[preferred] !== true) {
|
||||
if (option !== 'tab-size' && option !== 'space' && option !== 'mixed') {
|
||||
file.fail(
|
||||
'Incorrect list-item indent style `' +
|
||||
preferred +
|
||||
option +
|
||||
"`: use either `'tab-size'`, `'space'`, or `'mixed'`"
|
||||
)
|
||||
}
|
||||
@ -138,7 +141,8 @@ const remarkLintListItemIndent = lintRule(
|
||||
visit(tree, 'list', (node) => {
|
||||
if (generated(node)) return
|
||||
|
||||
const spread = node.spread || node.loose
|
||||
// @ts-expect-error: legacy.
|
||||
const spread = Boolean(node.spread || node.loose)
|
||||
let index = -1
|
||||
|
||||
while (++index < node.children.length) {
|
||||
@ -153,7 +157,7 @@ const remarkLintListItemIndent = lintRule(
|
||||
const bulletSize = marker.replace(/\s+$/, '').length
|
||||
|
||||
const style =
|
||||
preferred === 'tab-size' || (preferred === 'mixed' && spread)
|
||||
option === 'tab-size' || (option === 'mixed' && spread)
|
||||
? Math.ceil(bulletSize / 4) * 4
|
||||
: bulletSize + 1
|
||||
|
||||
|
@ -25,15 +25,28 @@
|
||||
"sideEffects": false,
|
||||
"type": "module",
|
||||
"main": "index.js",
|
||||
"types": "index.d.ts",
|
||||
"files": [
|
||||
"index.d.ts",
|
||||
"index.js"
|
||||
],
|
||||
"dependencies": {
|
||||
"@types/mdast": "^3.0.0",
|
||||
"pluralize": "^8.0.0",
|
||||
"unified": "^10.0.0",
|
||||
"unified-lint-rule": "^1.0.0",
|
||||
"unist-util-generated": "^2.0.0",
|
||||
"unist-util-position": "^4.0.0",
|
||||
"unist-util-visit": "^4.0.0"
|
||||
},
|
||||
"xo": false
|
||||
"scripts": {
|
||||
"build": "rimraf \"*.d.ts\" && tsc && type-coverage"
|
||||
},
|
||||
"xo": false,
|
||||
"typeCoverage": {
|
||||
"atLeast": 100,
|
||||
"detail": true,
|
||||
"strict": true,
|
||||
"ignoreCatch": true
|
||||
}
|
||||
}
|
||||
|
@ -191,12 +191,18 @@ When configured with `'💩'`.
|
||||
|
||||
## Install
|
||||
|
||||
This package is [ESM only][esm]:
|
||||
Node 12+ is needed to use it and it must be `imported`ed instead of `required`d.
|
||||
|
||||
[npm][]:
|
||||
|
||||
```sh
|
||||
npm install remark-lint-list-item-indent
|
||||
```
|
||||
|
||||
This package exports no identifiers.
|
||||
The default export is `remarkLintListItemIndent`.
|
||||
|
||||
## Use
|
||||
|
||||
You probably want to use it on the CLI through a config file:
|
||||
@ -277,6 +283,8 @@ abide by its terms.
|
||||
|
||||
[chat]: https://github.com/remarkjs/remark/discussions
|
||||
|
||||
[esm]: https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c
|
||||
|
||||
[npm]: https://docs.npmjs.com/cli/install
|
||||
|
||||
[health]: https://github.com/remarkjs/.github
|
||||
|
4
packages/remark-lint-list-item-indent/tsconfig.json
Normal file
4
packages/remark-lint-list-item-indent/tsconfig.json
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"include": ["*.js"]
|
||||
}
|
@ -113,6 +113,14 @@
|
||||
* 14:15-16:1: Extraneous new line after list item
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {import('mdast').Root} Root
|
||||
* @typedef {import('mdast').ListItem} ListItem
|
||||
*
|
||||
* @typedef Options
|
||||
* @property {boolean} [checkBlanks=false]
|
||||
*/
|
||||
|
||||
import {lintRule} from 'unified-lint-rule'
|
||||
import {visit} from 'unist-util-visit'
|
||||
import {pointStart, pointEnd} from 'unist-util-position'
|
||||
@ -120,6 +128,7 @@ import {generated} from 'unist-util-generated'
|
||||
|
||||
const remarkLintListItemSpacing = lintRule(
|
||||
'remark-lint:list-item-spacing',
|
||||
/** @type {import('unified-lint-rule').Rule<Root, Options>} */
|
||||
(tree, file, option = {}) => {
|
||||
const {checkBlanks} = option
|
||||
const infer = checkBlanks ? inferBlankLine : inferMultiline
|
||||
@ -158,6 +167,10 @@ const remarkLintListItemSpacing = lintRule(
|
||||
|
||||
export default remarkLintListItemSpacing
|
||||
|
||||
/**
|
||||
* @param {ListItem} node
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function inferBlankLine(node) {
|
||||
let index = 0
|
||||
|
||||
@ -174,6 +187,10 @@ function inferBlankLine(node) {
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {ListItem} node
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function inferMultiline(node) {
|
||||
return (
|
||||
pointEnd(node.children[node.children.length - 1]).line -
|
||||
|
@ -26,14 +26,27 @@
|
||||
"sideEffects": false,
|
||||
"type": "module",
|
||||
"main": "index.js",
|
||||
"types": "index.d.ts",
|
||||
"files": [
|
||||
"index.d.ts",
|
||||
"index.js"
|
||||
],
|
||||
"dependencies": {
|
||||
"@types/mdast": "^3.0.0",
|
||||
"unified": "^10.0.0",
|
||||
"unified-lint-rule": "^1.0.0",
|
||||
"unist-util-generated": "^2.0.0",
|
||||
"unist-util-position": "^4.0.0",
|
||||
"unist-util-visit": "^4.0.0"
|
||||
},
|
||||
"xo": false
|
||||
"scripts": {
|
||||
"build": "rimraf \"*.d.ts\" && tsc && type-coverage"
|
||||
},
|
||||
"xo": false,
|
||||
"typeCoverage": {
|
||||
"atLeast": 100,
|
||||
"detail": true,
|
||||
"strict": true,
|
||||
"ignoreCatch": true
|
||||
}
|
||||
}
|
||||
|
@ -156,12 +156,18 @@ A loose list:
|
||||
|
||||
## Install
|
||||
|
||||
This package is [ESM only][esm]:
|
||||
Node 12+ is needed to use it and it must be `imported`ed instead of `required`d.
|
||||
|
||||
[npm][]:
|
||||
|
||||
```sh
|
||||
npm install remark-lint-list-item-spacing
|
||||
```
|
||||
|
||||
This package exports no identifiers.
|
||||
The default export is `remarkLintListItemSpacing`.
|
||||
|
||||
## Use
|
||||
|
||||
You probably want to use it on the CLI through a config file:
|
||||
@ -242,6 +248,8 @@ abide by its terms.
|
||||
|
||||
[chat]: https://github.com/remarkjs/remark/discussions
|
||||
|
||||
[esm]: https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c
|
||||
|
||||
[npm]: https://docs.npmjs.com/cli/install
|
||||
|
||||
[health]: https://github.com/remarkjs/.github
|
||||
|
4
packages/remark-lint-list-item-spacing/tsconfig.json
Normal file
4
packages/remark-lint-list-item-spacing/tsconfig.json
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"include": ["*.js"]
|
||||
}
|
@ -28,6 +28,11 @@
|
||||
* 1:1-1:52: Use headings shorter than `40`
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {import('mdast').Root} Root
|
||||
* @typedef {number} Options
|
||||
*/
|
||||
|
||||
import {lintRule} from 'unified-lint-rule'
|
||||
import {visit} from 'unist-util-visit'
|
||||
import {generated} from 'unist-util-generated'
|
||||
@ -35,12 +40,11 @@ import {toString} from 'mdast-util-to-string'
|
||||
|
||||
const remarkLintMaximumHeadingLength = lintRule(
|
||||
'remark-lint:maximum-heading-length',
|
||||
(tree, file, option) => {
|
||||
const preferred = typeof option === 'number' ? option : 60
|
||||
|
||||
/** @type {import('unified-lint-rule').Rule<Root, Options>} */
|
||||
(tree, file, option = 60) => {
|
||||
visit(tree, 'heading', (node) => {
|
||||
if (!generated(node) && toString(node).length > preferred) {
|
||||
file.message('Use headings shorter than `' + preferred + '`', node)
|
||||
if (!generated(node) && toString(node).length > option) {
|
||||
file.message('Use headings shorter than `' + option + '`', node)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -24,14 +24,27 @@
|
||||
"sideEffects": false,
|
||||
"type": "module",
|
||||
"main": "index.js",
|
||||
"types": "index.d.ts",
|
||||
"files": [
|
||||
"index.d.ts",
|
||||
"index.js"
|
||||
],
|
||||
"dependencies": {
|
||||
"@types/mdast": "^3.0.0",
|
||||
"mdast-util-to-string": "^3.0.0",
|
||||
"unified": "^10.0.0",
|
||||
"unified-lint-rule": "^1.0.0",
|
||||
"unist-util-generated": "^2.0.0",
|
||||
"unist-util-visit": "^4.0.0"
|
||||
},
|
||||
"xo": false
|
||||
"scripts": {
|
||||
"build": "rimraf \"*.d.ts\" && tsc && type-coverage"
|
||||
},
|
||||
"xo": false,
|
||||
"typeCoverage": {
|
||||
"atLeast": 100,
|
||||
"detail": true,
|
||||
"strict": true,
|
||||
"ignoreCatch": true
|
||||
}
|
||||
}
|
||||
|
@ -58,12 +58,18 @@ No messages.
|
||||
|
||||
## Install
|
||||
|
||||
This package is [ESM only][esm]:
|
||||
Node 12+ is needed to use it and it must be `imported`ed instead of `required`d.
|
||||
|
||||
[npm][]:
|
||||
|
||||
```sh
|
||||
npm install remark-lint-maximum-heading-length
|
||||
```
|
||||
|
||||
This package exports no identifiers.
|
||||
The default export is `remarkLintMaximumHeadingLength`.
|
||||
|
||||
## Use
|
||||
|
||||
You probably want to use it on the CLI through a config file:
|
||||
@ -144,6 +150,8 @@ abide by its terms.
|
||||
|
||||
[chat]: https://github.com/remarkjs/remark/discussions
|
||||
|
||||
[esm]: https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c
|
||||
|
||||
[npm]: https://docs.npmjs.com/cli/install
|
||||
|
||||
[health]: https://github.com/remarkjs/.github
|
||||
|
@ -0,0 +1,4 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"include": ["*.js"]
|
||||
}
|
@ -96,6 +96,12 @@
|
||||
* 4:12: Line must be at most 10 characters
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {import('mdast').Root} Root
|
||||
* @typedef {import('mdast').Parent} Parent
|
||||
* @typedef {number} Options
|
||||
*/
|
||||
|
||||
import {lintRule} from 'unified-lint-rule'
|
||||
import {visit} from 'unist-util-visit'
|
||||
import {pointStart, pointEnd} from 'unist-util-position'
|
||||
@ -103,85 +109,93 @@ import {generated} from 'unist-util-generated'
|
||||
|
||||
const remarkLintMaximumLineLength = lintRule(
|
||||
'remark-lint:maximum-line-length',
|
||||
maximumLineLength
|
||||
/** @type {import('unified-lint-rule').Rule<Root, Options>} */
|
||||
(tree, file, option = 80) => {
|
||||
const value = String(file)
|
||||
const lines = value.split(/\r?\n/)
|
||||
|
||||
visit(tree, (node) => {
|
||||
if (
|
||||
(node.type === 'heading' ||
|
||||
node.type === 'table' ||
|
||||
node.type === 'code' ||
|
||||
node.type === 'definition' ||
|
||||
node.type === 'html' ||
|
||||
// @ts-expect-error: JSX is from MDX: <https://github.com/mdx-js/specification>.
|
||||
node.type === 'jsx' ||
|
||||
node.type === 'yaml' ||
|
||||
// @ts-expect-error: TOML is from frontmatter.
|
||||
node.type === 'toml') &&
|
||||
!generated(node)
|
||||
) {
|
||||
allowList(pointStart(node).line - 1, pointEnd(node).line)
|
||||
}
|
||||
})
|
||||
|
||||
// Finally, allow some inline spans, but only if they occur at or after
|
||||
// the wrap.
|
||||
// However, when they do, and there’s whitespace after it, they are not
|
||||
// allowed.
|
||||
visit(tree, (node, pos, parent_) => {
|
||||
const parent = /** @type {Parent} */ (parent_)
|
||||
|
||||
if (
|
||||
(node.type === 'link' ||
|
||||
node.type === 'image' ||
|
||||
node.type === 'inlineCode') &&
|
||||
!generated(node) &&
|
||||
parent &&
|
||||
typeof pos === 'number'
|
||||
) {
|
||||
const initial = pointStart(node)
|
||||
const final = pointEnd(node)
|
||||
|
||||
// Not allowing when starting after the border, or ending before it.
|
||||
if (initial.column > option || final.column < option) {
|
||||
return
|
||||
}
|
||||
|
||||
const next = parent.children[pos + 1]
|
||||
|
||||
// Not allowing when there’s whitespace after the link.
|
||||
if (
|
||||
next &&
|
||||
pointStart(next).line === initial.line &&
|
||||
(!('value' in next) || /^(.+?[ \t].+?)/.test(next.value))
|
||||
) {
|
||||
return
|
||||
}
|
||||
|
||||
allowList(initial.line - 1, final.line)
|
||||
}
|
||||
})
|
||||
|
||||
// Iterate over every line, and warn for violating lines.
|
||||
let index = -1
|
||||
|
||||
while (++index < lines.length) {
|
||||
const lineLength = lines[index].length
|
||||
|
||||
if (lineLength > option) {
|
||||
file.message('Line must be at most ' + option + ' characters', {
|
||||
line: index + 1,
|
||||
column: lineLength + 1
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Allowlist from `initial` to `final`, zero-based.
|
||||
*
|
||||
* @param {number} initial
|
||||
* @param {number} final
|
||||
*/
|
||||
function allowList(initial, final) {
|
||||
while (initial < final) {
|
||||
lines[initial++] = ''
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
export default remarkLintMaximumLineLength
|
||||
|
||||
function maximumLineLength(tree, file, option) {
|
||||
const preferred = typeof option === 'number' ? option : 80
|
||||
const value = String(file)
|
||||
const lines = value.split(/\r?\n/)
|
||||
|
||||
visit(tree, (node) => {
|
||||
// Note: JSX is from MDX: <https://github.com/mdx-js/specification>.
|
||||
if (
|
||||
(node.type === 'heading' ||
|
||||
node.type === 'table' ||
|
||||
node.type === 'code' ||
|
||||
node.type === 'definition' ||
|
||||
node.type === 'html' ||
|
||||
node.type === 'jsx' ||
|
||||
node.type === 'yaml' ||
|
||||
node.type === 'toml') &&
|
||||
!generated(node)
|
||||
) {
|
||||
allowList(pointStart(node).line - 1, pointEnd(node).line)
|
||||
}
|
||||
})
|
||||
|
||||
// Finally, allow some inline spans, but only if they occur at or after
|
||||
// the wrap.
|
||||
// However, when they do, and there’s whitespace after it, they are not
|
||||
// allowed.
|
||||
visit(tree, (node, pos, parent) => {
|
||||
if (
|
||||
(node.type === 'link' ||
|
||||
node.type === 'image' ||
|
||||
node.type === 'inlineCode') &&
|
||||
!generated(node)
|
||||
) {
|
||||
const initial = pointStart(node)
|
||||
const final = pointEnd(node)
|
||||
|
||||
// Not allowing when starting after the border, or ending before it.
|
||||
if (initial.column > preferred || final.column < preferred) {
|
||||
return
|
||||
}
|
||||
|
||||
const next = parent.children[pos + 1]
|
||||
|
||||
// Not allowing when there’s whitespace after the link.
|
||||
if (
|
||||
next &&
|
||||
pointStart(next).line === initial.line &&
|
||||
(!next.value || /^(.+?[ \t].+?)/.test(next.value))
|
||||
) {
|
||||
return
|
||||
}
|
||||
|
||||
allowList(initial.line - 1, final.line)
|
||||
}
|
||||
})
|
||||
|
||||
// Iterate over every line, and warn for violating lines.
|
||||
let index = -1
|
||||
|
||||
while (++index < lines.length) {
|
||||
const lineLength = lines[index].length
|
||||
|
||||
if (lineLength > preferred) {
|
||||
file.message('Line must be at most ' + preferred + ' characters', {
|
||||
line: index + 1,
|
||||
column: lineLength + 1
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Allowlist from `initial` to `final`, zero-based.
|
||||
function allowList(initial, final) {
|
||||
while (initial < final) {
|
||||
lines[initial++] = ''
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -24,14 +24,27 @@
|
||||
"sideEffects": false,
|
||||
"type": "module",
|
||||
"main": "index.js",
|
||||
"types": "index.d.ts",
|
||||
"files": [
|
||||
"index.d.ts",
|
||||
"index.js"
|
||||
],
|
||||
"dependencies": {
|
||||
"@types/mdast": "^3.0.0",
|
||||
"unified": "^10.0.0",
|
||||
"unified-lint-rule": "^1.0.0",
|
||||
"unist-util-generated": "^2.0.0",
|
||||
"unist-util-position": "^4.0.0",
|
||||
"unist-util-visit": "^4.0.0"
|
||||
},
|
||||
"xo": false
|
||||
"scripts": {
|
||||
"build": "rimraf \"*.d.ts\" && tsc && type-coverage"
|
||||
},
|
||||
"xo": false,
|
||||
"typeCoverage": {
|
||||
"atLeast": 100,
|
||||
"detail": true,
|
||||
"strict": true,
|
||||
"ignoreCatch": true
|
||||
}
|
||||
}
|
||||
|
@ -151,12 +151,18 @@ No messages.
|
||||
|
||||
## Install
|
||||
|
||||
This package is [ESM only][esm]:
|
||||
Node 12+ is needed to use it and it must be `imported`ed instead of `required`d.
|
||||
|
||||
[npm][]:
|
||||
|
||||
```sh
|
||||
npm install remark-lint-maximum-line-length
|
||||
```
|
||||
|
||||
This package exports no identifiers.
|
||||
The default export is `remarkLintMaximumLineLength`.
|
||||
|
||||
## Use
|
||||
|
||||
You probably want to use it on the CLI through a config file:
|
||||
@ -237,6 +243,8 @@ abide by its terms.
|
||||
|
||||
[chat]: https://github.com/remarkjs/remark/discussions
|
||||
|
||||
[esm]: https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c
|
||||
|
||||
[npm]: https://docs.npmjs.com/cli/install
|
||||
|
||||
[health]: https://github.com/remarkjs/.github
|
||||
|
4
packages/remark-lint-maximum-line-length/tsconfig.json
Normal file
4
packages/remark-lint-maximum-line-length/tsconfig.json
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"include": ["*.js"]
|
||||
}
|
@ -36,6 +36,10 @@
|
||||
* 1:1-1:14: All automatic links must start with a protocol
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {import('mdast').Root} Root
|
||||
*/
|
||||
|
||||
import {lintRule} from 'unified-lint-rule'
|
||||
import {visit} from 'unist-util-visit'
|
||||
import {pointStart, pointEnd} from 'unist-util-position'
|
||||
@ -48,6 +52,7 @@ const protocol = /^[a-z][a-z+.-]+:\/?/i
|
||||
|
||||
const remarkLintNoAutoLinkWithoutProtocol = lintRule(
|
||||
'remark-lint:no-auto-link-without-protocol',
|
||||
/** @type {import('unified-lint-rule').Rule<Root, void>} */
|
||||
(tree, file) => {
|
||||
visit(tree, 'link', (node) => {
|
||||
if (
|
||||
|
@ -25,15 +25,28 @@
|
||||
"sideEffects": false,
|
||||
"type": "module",
|
||||
"main": "index.js",
|
||||
"types": "index.d.ts",
|
||||
"files": [
|
||||
"index.d.ts",
|
||||
"index.js"
|
||||
],
|
||||
"dependencies": {
|
||||
"@types/mdast": "^3.0.0",
|
||||
"mdast-util-to-string": "^3.0.0",
|
||||
"unified": "^10.0.0",
|
||||
"unified-lint-rule": "^1.0.0",
|
||||
"unist-util-generated": "^2.0.0",
|
||||
"unist-util-position": "^4.0.0",
|
||||
"unist-util-visit": "^4.0.0"
|
||||
},
|
||||
"xo": false
|
||||
"scripts": {
|
||||
"build": "rimraf \"*.d.ts\" && tsc && type-coverage"
|
||||
},
|
||||
"xo": false,
|
||||
"typeCoverage": {
|
||||
"atLeast": 100,
|
||||
"detail": true,
|
||||
"strict": true,
|
||||
"ignoreCatch": true
|
||||
}
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user