markdownlint 0.20.2 → 0.21.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/CONTRIBUTING.md +50 -47
  2. package/LICENSE +21 -21
  3. package/README.md +915 -871
  4. package/demo/markdownlint-browser.js +4693 -5400
  5. package/doc/CustomRules.md +315 -313
  6. package/doc/Rules.md +1868 -1795
  7. package/helpers/LICENSE +21 -21
  8. package/helpers/README.md +50 -50
  9. package/helpers/helpers.js +690 -671
  10. package/helpers/package.json +18 -18
  11. package/lib/cache.js +24 -24
  12. package/lib/markdownlint.d.ts +365 -352
  13. package/lib/markdownlint.js +1186 -1101
  14. package/lib/md001.js +22 -22
  15. package/lib/md002.js +22 -22
  16. package/lib/md003.js +42 -42
  17. package/lib/md004.js +43 -43
  18. package/lib/md005.js +69 -69
  19. package/lib/md006.js +34 -34
  20. package/lib/md007.js +47 -47
  21. package/lib/md009.js +77 -77
  22. package/lib/md010.js +38 -38
  23. package/lib/md011.js +42 -38
  24. package/lib/md012.js +32 -32
  25. package/lib/md013.js +99 -99
  26. package/lib/md014.js +53 -53
  27. package/lib/md018.js +34 -34
  28. package/lib/md019.js +39 -39
  29. package/lib/md020.js +62 -62
  30. package/lib/md021.js +60 -60
  31. package/lib/md022.js +56 -56
  32. package/lib/md023.js +38 -38
  33. package/lib/md024.js +38 -38
  34. package/lib/md025.js +32 -32
  35. package/lib/md026.js +40 -40
  36. package/lib/md027.js +56 -56
  37. package/lib/md028.js +38 -38
  38. package/lib/md029.js +66 -66
  39. package/lib/md030.js +50 -50
  40. package/lib/md031.js +40 -39
  41. package/lib/md032.js +50 -50
  42. package/lib/md033.js +45 -45
  43. package/lib/md034.js +61 -61
  44. package/lib/md035.js +21 -21
  45. package/lib/md036.js +56 -56
  46. package/lib/md037.js +150 -141
  47. package/lib/md038.js +68 -68
  48. package/lib/md039.js +64 -64
  49. package/lib/md040.js +18 -18
  50. package/lib/md041.js +31 -31
  51. package/lib/md042.js +42 -41
  52. package/lib/md043.js +45 -45
  53. package/lib/md044.js +94 -71
  54. package/lib/md045.js +18 -18
  55. package/lib/md046.js +32 -32
  56. package/lib/md047.js +28 -28
  57. package/lib/md048.js +29 -29
  58. package/lib/rules.js +60 -61
  59. package/package.json +74 -67
  60. package/schema/build-config-schema.js +409 -405
  61. package/schema/markdownlint-config-schema.json +7 -2
  62. package/style/all.json +5 -5
  63. package/style/cirosantilli.json +22 -22
  64. package/style/relaxed.json +13 -13
package/README.md CHANGED
@@ -1,871 +1,915 @@
1
- # markdownlint
2
-
3
- > A Node.js style checker and lint tool for Markdown/CommonMark files.
4
-
5
- [![npm version][npm-image]][npm-url]
6
- [![CI Status][ci-image]][ci-url]
7
- [![License][license-image]][license-url]
8
-
9
- ## Install
10
-
11
- ```shell
12
- npm install markdownlint --save-dev
13
- ```
14
-
15
- ## Overview
16
-
17
- The [Markdown](https://en.wikipedia.org/wiki/Markdown) markup language is
18
- designed to be easy to read, write, and understand. It succeeds - and its
19
- flexibility is both a benefit and a drawback. Many styles are possible, so
20
- formatting can be inconsistent. Some constructs don't work well in all
21
- parsers and should be avoided. The [CommonMark](https://commonmark.org/)
22
- specification standardizes parsers - but not authors.
23
-
24
- `markdownlint` is a
25
- [static analysis](https://en.wikipedia.org/wiki/Static_program_analysis)
26
- tool for [Node.js](https://nodejs.org/) with a library of rules
27
- to enforce standards and consistency for Markdown files. It was
28
- inspired by - and heavily influenced by - Mark Harrison's
29
- [markdownlint](https://github.com/markdownlint/markdownlint) for
30
- [Ruby](https://www.ruby-lang.org/). The initial rules, rule documentation,
31
- and test cases came directly from that project.
32
-
33
- ### Related
34
-
35
- * [markdownlint-cli command-line interface for Node.js](https://github.com/igorshubovych/markdownlint-cli)
36
- * [grunt-markdownlint for the Grunt task runner](https://github.com/sagiegurari/grunt-markdownlint)
37
- * [vscode-markdownlint extension for VS Code](https://marketplace.visualstudio.com/items/DavidAnson.vscode-markdownlint)
38
- * [Sublime Text markdownlint for Sublime Text](https://packagecontrol.io/packages/SublimeLinter-contrib-markdownlint)
39
- * [linter-node-markdownlint extension for Atom](https://atom.io/packages/linter-node-markdownlint)
40
- * [coc-markdownlint extension for Vim/Neovim](https://github.com/fannheyward/coc-markdownlint)
41
- * [markdownlint/mdl gem for Ruby](https://rubygems.org/gems/mdl)
42
- * [Cake.Markdownlint addin for Cake build automation system](https://github.com/cake-contrib/Cake.Markdownlint)
43
-
44
- ## Demonstration
45
-
46
- [`markdownlint` demo](https://dlaa.me/markdownlint/), an interactive, in-browser
47
- playground for learning and exploring.
48
-
49
- ## Rules / Aliases
50
-
51
- * **[MD001](doc/Rules.md#md001)** *heading-increment/header-increment* - Heading levels should only increment by one level at a time
52
- * ~~**[MD002](doc/Rules.md#md002)** *first-heading-h1/first-header-h1* - First heading should be a top level heading~~
53
- * **[MD003](doc/Rules.md#md003)** *heading-style/header-style* - Heading style
54
- * **[MD004](doc/Rules.md#md004)** *ul-style* - Unordered list style
55
- * **[MD005](doc/Rules.md#md005)** *list-indent* - Inconsistent indentation for list items at the same level
56
- * ~~**[MD006](doc/Rules.md#md006)** *ul-start-left* - Consider starting bulleted lists at the beginning of the line~~
57
- * **[MD007](doc/Rules.md#md007)** *ul-indent* - Unordered list indentation
58
- * **[MD009](doc/Rules.md#md009)** *no-trailing-spaces* - Trailing spaces
59
- * **[MD010](doc/Rules.md#md010)** *no-hard-tabs* - Hard tabs
60
- * **[MD011](doc/Rules.md#md011)** *no-reversed-links* - Reversed link syntax
61
- * **[MD012](doc/Rules.md#md012)** *no-multiple-blanks* - Multiple consecutive blank lines
62
- * **[MD013](doc/Rules.md#md013)** *line-length* - Line length
63
- * **[MD014](doc/Rules.md#md014)** *commands-show-output* - Dollar signs used before commands without showing output
64
- * **[MD018](doc/Rules.md#md018)** *no-missing-space-atx* - No space after hash on atx style heading
65
- * **[MD019](doc/Rules.md#md019)** *no-multiple-space-atx* - Multiple spaces after hash on atx style heading
66
- * **[MD020](doc/Rules.md#md020)** *no-missing-space-closed-atx* - No space inside hashes on closed atx style heading
67
- * **[MD021](doc/Rules.md#md021)** *no-multiple-space-closed-atx* - Multiple spaces inside hashes on closed atx style heading
68
- * **[MD022](doc/Rules.md#md022)** *blanks-around-headings/blanks-around-headers* - Headings should be surrounded by blank lines
69
- * **[MD023](doc/Rules.md#md023)** *heading-start-left/header-start-left* - Headings must start at the beginning of the line
70
- * **[MD024](doc/Rules.md#md024)** *no-duplicate-heading/no-duplicate-header* - Multiple headings with the same content
71
- * **[MD025](doc/Rules.md#md025)** *single-title/single-h1* - Multiple top level headings in the same document
72
- * **[MD026](doc/Rules.md#md026)** *no-trailing-punctuation* - Trailing punctuation in heading
73
- * **[MD027](doc/Rules.md#md027)** *no-multiple-space-blockquote* - Multiple spaces after blockquote symbol
74
- * **[MD028](doc/Rules.md#md028)** *no-blanks-blockquote* - Blank line inside blockquote
75
- * **[MD029](doc/Rules.md#md029)** *ol-prefix* - Ordered list item prefix
76
- * **[MD030](doc/Rules.md#md030)** *list-marker-space* - Spaces after list markers
77
- * **[MD031](doc/Rules.md#md031)** *blanks-around-fences* - Fenced code blocks should be surrounded by blank lines
78
- * **[MD032](doc/Rules.md#md032)** *blanks-around-lists* - Lists should be surrounded by blank lines
79
- * **[MD033](doc/Rules.md#md033)** *no-inline-html* - Inline HTML
80
- * **[MD034](doc/Rules.md#md034)** *no-bare-urls* - Bare URL used
81
- * **[MD035](doc/Rules.md#md035)** *hr-style* - Horizontal rule style
82
- * **[MD036](doc/Rules.md#md036)** *no-emphasis-as-heading/no-emphasis-as-header* - Emphasis used instead of a heading
83
- * **[MD037](doc/Rules.md#md037)** *no-space-in-emphasis* - Spaces inside emphasis markers
84
- * **[MD038](doc/Rules.md#md038)** *no-space-in-code* - Spaces inside code span elements
85
- * **[MD039](doc/Rules.md#md039)** *no-space-in-links* - Spaces inside link text
86
- * **[MD040](doc/Rules.md#md040)** *fenced-code-language* - Fenced code blocks should have a language specified
87
- * **[MD041](doc/Rules.md#md041)** *first-line-heading/first-line-h1* - First line in file should be a top level heading
88
- * **[MD042](doc/Rules.md#md042)** *no-empty-links* - No empty links
89
- * **[MD043](doc/Rules.md#md043)** *required-headings/required-headers* - Required heading structure
90
- * **[MD044](doc/Rules.md#md044)** *proper-names* - Proper names should have the correct capitalization
91
- * **[MD045](doc/Rules.md#md045)** *no-alt-text* - Images should have alternate text (alt text)
92
- * **[MD046](doc/Rules.md#md046)** *code-block-style* - Code block style
93
- * **[MD047](doc/Rules.md#md047)** *single-trailing-newline* - Files should end with a single newline character
94
- * **[MD048](doc/Rules.md#md048)** *code-fence-style* - Code fence style
95
-
96
- See [Rules.md](doc/Rules.md) for more details.
97
-
98
- ~~Struck through~~ rules are deprecated, and provided for backward-compatibility.
99
-
100
- > All rules with `heading` as part of their name are also available as `header`
101
- > aliases (e.g. `heading-increment` is also available as `header-increment`).
102
- > The use of `header` is deprecated and provided for backward-compatibility.
103
-
104
- ## Tags
105
-
106
- Tags group related rules and can be used to enable/disable multiple rules at once.
107
-
108
- * **accessibility** - MD045
109
- * **atx** - MD018, MD019
110
- * **atx_closed** - MD020, MD021
111
- * **blank_lines** - MD012, MD022, MD031, MD032, MD047
112
- * **blockquote** - MD027, MD028
113
- * **bullet** - MD004, MD005, MD006, MD007, MD032
114
- * **code** - MD014, MD031, MD038, MD040, MD046, MD048
115
- * **emphasis** - MD036, MD037
116
- * **hard_tab** - MD010
117
- * **headers** - MD001, MD002, MD003, MD018, MD019, MD020, MD021, MD022, MD023,
118
- MD024, MD025, MD026, MD036, MD041, MD043
119
- * **headings** - MD001, MD002, MD003, MD018, MD019, MD020, MD021, MD022, MD023,
120
- MD024, MD025, MD026, MD036, MD041, MD043
121
- * **hr** - MD035
122
- * **html** - MD033
123
- * **images** - MD045
124
- * **indentation** - MD005, MD006, MD007, MD027
125
- * **language** - MD040
126
- * **line_length** - MD013
127
- * **links** - MD011, MD034, MD039, MD042
128
- * **ol** - MD029, MD030, MD032
129
- * **spaces** - MD018, MD019, MD020, MD021, MD023
130
- * **spelling** - MD044
131
- * **ul** - MD004, MD005, MD006, MD007, MD030, MD032
132
- * **url** - MD034
133
- * **whitespace** - MD009, MD010, MD012, MD027, MD028, MD030, MD037, MD038, MD039
134
-
135
- ## Configuration
136
-
137
- Text passed to `markdownlint` is parsed as Markdown, analyzed, and any issues reported.
138
- Two kinds of text are ignored:
139
-
140
- * [HTML comments](https://www.w3.org/TR/html5/syntax.html#comments)
141
- * [Front matter](https://jekyllrb.com/docs/frontmatter/) (see `options.frontMatter` below)
142
-
143
- Rules can be enabled, disabled, and configured via `options.config` (described
144
- below) to define the expected behavior for a set of inputs. To enable or disable
145
- rules at a particular location within a file, add one of these markers to the
146
- appropriate place (HTML comments don't appear in the final markup):
147
-
148
- * Disable all rules: `<!-- markdownlint-disable -->`
149
- * Enable all rules: `<!-- markdownlint-enable -->`
150
- * Disable one or more rules by name: `<!-- markdownlint-disable MD001 MD005 -->`
151
- * Enable one or more rules by name: `<!-- markdownlint-enable MD001 MD005 -->`
152
- * Capture the current rule configuration: `<!-- markdownlint-capture -->`
153
- * Restore the captured rule configuration: `<!-- markdownlint-restore -->`
154
-
155
- For example:
156
-
157
- ```markdown
158
- <!-- markdownlint-disable no-space-in-emphasis -->
159
- deliberate space * in * emphasis
160
- <!-- markdownlint-enable no-space-in-emphasis -->
161
- ```
162
-
163
- To temporarily disable rule(s), then restore the former configuration:
164
-
165
- ```markdown
166
- <!-- markdownlint-capture -->
167
- <!-- markdownlint-disable -->
168
- any violations you want
169
- <!-- markdownlint-restore -->
170
- ```
171
-
172
- The initial configuration is captured by default (as if every document began
173
- with `<!-- markdownlint-capture -->`), so the pattern above can be expressed
174
- more simply:
175
-
176
- ```markdown
177
- <!-- markdownlint-disable -->
178
- any violations you want
179
- <!-- markdownlint-restore -->
180
- ```
181
-
182
- Changes take effect starting with the line a comment is on, so the following
183
- has no effect:
184
-
185
- ```markdown
186
- space * in * emphasis <!-- markdownlint-disable --> <!-- markdownlint-enable -->
187
- ```
188
-
189
- To apply changes to an entire file regardless of where the comment is located,
190
- the following syntax is supported:
191
-
192
- * Disable all rules: `<!-- markdownlint-disable-file -->`
193
- * Enable all rules: `<!-- markdownlint-enable-file -->`
194
- * Disable one or more rules by name: `<!-- markdownlint-disable-file MD001 -->`
195
- * Enable one or more rules by name: `<!-- markdownlint-enable-file MD001 -->`
196
-
197
- This can be used to "hide" `markdownlint` comments at the bottom of a file.
198
-
199
- In cases where it is desirable to change the configuration of one or more rules
200
- for a file, the following more advanced syntax is supported:
201
-
202
- * Confiure: `<!-- markdownlint-configure-file { options.config JSON } -->`
203
-
204
- For example:
205
-
206
- ```markdown
207
- <!-- markdownlint-configure-file { "MD013": { "line_length": 70 } } -->
208
- ```
209
-
210
- or
211
-
212
- ```markdown
213
- <!-- markdownlint-configure-file
214
- {
215
- "hr-style": {
216
- "style": "---"
217
- },
218
- "no-trailing-spaces": false
219
- }
220
- -->
221
- ```
222
-
223
- These changes apply to the entire file regardless of where the comment is
224
- located. Multiple such comments (if present) are applied top-to-bottom.
225
-
226
- ## API
227
-
228
- ### Linting
229
-
230
- Standard asynchronous interface:
231
-
232
- ```js
233
- /**
234
- * Lint specified Markdown files.
235
- *
236
- * @param {Object} options Configuration options.
237
- * @param {Function} callback Callback (err, result) function.
238
- * @returns {void}
239
- */
240
- function markdownlint(options, callback) { ... }
241
- ```
242
-
243
- Synchronous interface (for build scripts, etc.):
244
-
245
- ```js
246
- /**
247
- * Lint specified Markdown files synchronously.
248
- *
249
- * @param {Object} options Configuration options.
250
- * @returns {Object} Result object.
251
- */
252
- function markdownlint.sync(options) { ... }
253
- ```
254
-
255
- #### options
256
-
257
- Type: `Object`
258
-
259
- Configures the function.
260
-
261
- ##### options.customRules
262
-
263
- Type: `Array` of `Object`
264
-
265
- List of custom rules to include with the default rule set for linting.
266
-
267
- Each array element should define a rule. Rules are typically exported by another
268
- package, but can be defined inline.
269
-
270
- Example:
271
-
272
- ```js
273
- const extraRules = require("extraRules");
274
- const options = {
275
- "customRules": [ extraRules.one, extraRules.two ]
276
- };
277
- ```
278
-
279
- See [CustomRules.md](doc/CustomRules.md) for details about authoring custom rules.
280
-
281
- ##### options.files
282
-
283
- Type: `Array` of `String`
284
-
285
- List of files to lint.
286
-
287
- Each array element should be a single file (via relative or absolute path);
288
- [globbing](https://en.wikipedia.org/wiki/Glob_%28programming%29) is the caller's
289
- responsibility.
290
-
291
- Example: `[ "one.md", "dir/two.md" ]`
292
-
293
- ##### options.strings
294
-
295
- Type: `Object` mapping `String` to `String`
296
-
297
- Map of identifiers to strings for linting.
298
-
299
- When Markdown content is not available as files, it can be passed as strings.
300
- The keys of the `strings` object are used to identify each input value in the
301
- `result` summary.
302
-
303
- Example:
304
-
305
- ```json
306
- {
307
- "readme": "# README\n...",
308
- "changelog": "# CHANGELOG\n..."
309
- }
310
- ```
311
-
312
- ##### options.config
313
-
314
- Type: `Object` mapping `String` to `Boolean | Object`
315
-
316
- Configures the rules to use.
317
-
318
- Object keys are rule names or aliases and values are the rule's configuration.
319
- The value `false` disables a rule, `true` enables its default configuration,
320
- and passing an object customizes its settings. Setting the special `default`
321
- rule to `true` or `false` includes/excludes all rules by default. Enabling or
322
- disabling a tag name (ex: `whitespace`) affects all rules having that tag.
323
-
324
- The `default` rule is applied first, then keys are processed in order from top
325
- to bottom with later values overriding earlier ones. Keys (including rule names,
326
- aliases, tags, and `default`) are not case-sensitive.
327
-
328
- Example:
329
-
330
- ```json
331
- {
332
- "default": true,
333
- "MD003": { "style": "atx_closed" },
334
- "MD007": { "indent": 4 },
335
- "no-hard-tabs": false,
336
- "whitespace": false
337
- }
338
- ```
339
-
340
- Sets of rules (known as a "style") can be stored separately and loaded as
341
- [JSON](https://en.wikipedia.org/wiki/JSON).
342
-
343
- Example:
344
-
345
- ```js
346
- const options = {
347
- "files": [ "..." ],
348
- "config": require("style/relaxed.json")
349
- };
350
- ```
351
-
352
- See the [style](style) directory for more samples.
353
-
354
- See [markdownlint-config-schema.json](schema/markdownlint-config-schema.json)
355
- for the [JSON Schema](https://json-schema.org/) of the `options.config` object.
356
-
357
- For more advanced scenarios, styles can reference and extend other styles. The
358
- `readConfig` and `readConfigSync` functions can be used to read such styles.
359
-
360
- For example, assuming a `base.json` configuration file:
361
-
362
- ```json
363
- {
364
- "default": true
365
- }
366
- ```
367
-
368
- And a `custom.json` configuration file:
369
-
370
- ```json
371
- {
372
- "extends": "base.json",
373
- "line-length": false
374
- }
375
- ```
376
-
377
- Then code like the following:
378
-
379
- ```js
380
- const options = {
381
- "config": markdownlint.readConfigSync("./custom.json")
382
- };
383
- ```
384
-
385
- Merges `custom.json` and `base.json` and is equivalent to:
386
-
387
- ```js
388
- const options = {
389
- "config": {
390
- "default": true,
391
- "line-length": false
392
- }
393
- };
394
- ```
395
-
396
- ##### options.frontMatter
397
-
398
- Type: `RegExp`
399
-
400
- Matches any [front matter](https://jekyllrb.com/docs/frontmatter/) found at the
401
- beginning of a file.
402
-
403
- Some Markdown content begins with metadata; the default `RegExp` for this option
404
- ignores common forms of "front matter". To match differently, specify a custom
405
- `RegExp` or use the value `null` to disable the feature.
406
-
407
- The default value:
408
-
409
- ```js
410
- /((^---\s*$[^]*?^---\s*$)|(^\+\+\+\s*$[^]*?^(\+\+\+|\.\.\.)\s*$))(\r\n|\r|\n|$)/m
411
- ```
412
-
413
- Ignores [YAML](https://en.wikipedia.org/wiki/YAML) and
414
- [TOML](https://en.wikipedia.org/wiki/TOML) such as:
415
-
416
- ```text
417
- ---
418
- layout: post
419
- title: Title
420
- ---
421
- ```
422
-
423
- Note: Matches must occur at the start of the file.
424
-
425
- ##### options.handleRuleFailures
426
-
427
- Type: `Boolean`
428
-
429
- Catches exceptions thrown during rule processing and reports the problem as a
430
- rule violation.
431
-
432
- By default, exceptions thrown by rules (or the library itself) are unhandled
433
- and bubble up the stack to the caller in the conventional manner. By setting
434
- `handleRuleFailures` to `true`, exceptions thrown by failing rules will be
435
- handled by the library and the exception message logged as a rule violation.
436
- This setting can be useful in the presence of (custom) rules that encounter
437
- unexpected syntax and fail. By enabling this option, the linting process is
438
- allowed to continue and report any violations that were found.
439
-
440
- ##### options.noInlineConfig
441
-
442
- Type: `Boolean`
443
-
444
- Disables the use of HTML comments like `<!-- markdownlint-disable -->` to toggle
445
- rules within the body of Markdown content.
446
-
447
- By default, properly-formatted inline comments can be used to create exceptions
448
- for parts of a document. Setting `noInlineConfig` to `true` ignores all such
449
- comments.
450
-
451
- ##### options.resultVersion
452
-
453
- Type: `Number`
454
-
455
- Specifies which version of the `result` object to return (see the "Usage" section
456
- below for examples).
457
-
458
- Passing a `resultVersion` of `0` corresponds to the original, simple format where
459
- each error is identified by rule name and line number. *This is deprecated.*
460
-
461
- Passing a `resultVersion` of `1` corresponds to a detailed format where each error
462
- includes information about the line number, rule name, alias, description, as well
463
- as any additional detail or context that is available. *This is deprecated.*
464
-
465
- Passing a `resultVersion` of `2` corresponds to a detailed format where each error
466
- includes information about the line number, rule names, description, as well as any
467
- additional detail or context that is available. *This is the default.*
468
-
469
- Passing a `resultVersion` of `3` corresponds to the detailed version `2` format
470
- with additional information about how to fix automatically-fixable errors. In this
471
- mode, all errors that occur on each line are reported (other versions report only
472
- the first error for each rule).
473
-
474
- ##### options.markdownItPlugins
475
-
476
- Type: `Array` of `Array` of `Function` and plugin parameters
477
-
478
- Specifies additional [markdown-it plugins](https://www.npmjs.com/search?q=keywords:markdown-it-plugin)
479
- to use when parsing input. Plugins can be used to support additional syntax and
480
- features for advanced scenarios.
481
-
482
- Each item in the top-level `Array` should be of the form:
483
-
484
- ```js
485
- [ require("markdown-it-plugin"), plugin_param_0, plugin_param_1, ... ]
486
- ```
487
-
488
- #### callback
489
-
490
- Type: `Function` taking (`Error`, `Object`)
491
-
492
- Standard completion callback.
493
-
494
- #### result
495
-
496
- Type: `Object`
497
-
498
- Call `result.toString()` for convenience or see below for an example of the
499
- structure of the `result` object. Passing the value `true` to `toString()`
500
- uses rule aliases (ex: `no-hard-tabs`) instead of names (ex: `MD010`).
501
-
502
- ### Config
503
-
504
- The `options.config` configuration object is simple and can be stored in a file
505
- for readability and easy reuse. The `readConfig` and `readConfigSync` functions
506
- load configuration settings and support the `extends` keyword for referencing
507
- other files (see above).
508
-
509
- By default, configuration files are parsed as JSON (and named `.markdownlint.json`).
510
- Custom parsers can be provided to handle other formats like JSONC, YAML, and TOML.
511
-
512
- Asynchronous interface:
513
-
514
- ```js
515
- /**
516
- * Read specified configuration file.
517
- *
518
- * @param {String} file Configuration file name/path.
519
- * @param {Array} [parsers] Optional parsing function(s).
520
- * @param {Function} callback Callback (err, result) function.
521
- * @returns {void}
522
- */
523
- function readConfig(file, parsers, callback) { ... }
524
- ```
525
-
526
- Synchronous interface:
527
-
528
- ```js
529
- /**
530
- * Read specified configuration file synchronously.
531
- *
532
- * @param {String} file Configuration file name/path.
533
- * @param {Array} [parsers] Optional parsing function(s).
534
- * @returns {Object} Configuration object.
535
- */
536
- function readConfigSync(file, parsers) { ... }
537
- ```
538
-
539
- #### file
540
-
541
- Type: `String`
542
-
543
- Location of configuration file to read.
544
-
545
- The `file` is resolved relative to the current working directory. If an `extends`
546
- key is present once read, its value will be resolved as a path relative to `file`
547
- and loaded recursively. Settings from a file referenced by `extends` are applied
548
- first, then those of `file` are applied on top (overriding any of the same keys
549
- appearing in the referenced file).
550
-
551
- #### parsers
552
-
553
- Type: *Optional* `Array` of `Function` taking (`String`) and returning `Object`
554
-
555
- Array of functions to parse configuration files.
556
-
557
- The contents of a configuration file are passed to each parser function until one
558
- of them returns a value (vs. throwing an exception). Consequently, strict parsers
559
- should come before flexible parsers.
560
-
561
- For example:
562
-
563
- ```js
564
- [ JSON.parse, require("toml").parse, require("js-yaml").safeLoad ]
565
- ```
566
-
567
- #### callback
568
-
569
- Type: `Function` taking (`Error`, `Object`)
570
-
571
- Standard completion callback.
572
-
573
- #### result
574
-
575
- Type: `Object`
576
-
577
- Configuration object.
578
-
579
- ## Usage
580
-
581
- Invoke `markdownlint` and use the `result` object's `toString` method:
582
-
583
- ```js
584
- const markdownlint = require("markdownlint");
585
-
586
- const options = {
587
- "files": [ "good.md", "bad.md" ],
588
- "strings": {
589
- "good.string": "# good.string\n\nThis string passes all rules.",
590
- "bad.string": "#bad.string\n\n#This string fails\tsome rules."
591
- }
592
- };
593
-
594
- markdownlint(options, function callback(err, result) {
595
- if (!err) {
596
- console.log(result.toString());
597
- }
598
- });
599
- ```
600
-
601
- Output:
602
-
603
- ```text
604
- bad.string: 3: MD010/no-hard-tabs Hard tabs [Column: 19]
605
- bad.string: 1: MD018/no-missing-space-atx No space after hash on atx style heading [Context: "#bad.string"]
606
- bad.string: 3: MD018/no-missing-space-atx No space after hash on atx style heading [Context: "#This string fails some rules."]
607
- bad.string: 1: MD041/first-line-heading/first-line-h1 First line in file should be a top level heading [Context: "#bad.string"]
608
- bad.md: 3: MD010/no-hard-tabs Hard tabs [Column: 17]
609
- bad.md: 1: MD018/no-missing-space-atx No space after hash on atx style heading [Context: "#bad.md"]
610
- bad.md: 3: MD018/no-missing-space-atx No space after hash on atx style heading [Context: "#This file fails some rules."]
611
- bad.md: 1: MD041/first-line-heading/first-line-h1 First line in file should be a top level heading [Context: "#bad.md"]
612
- ```
613
-
614
- Or invoke `markdownlint.sync` for a synchronous call:
615
-
616
- ```js
617
- const result = markdownlint.sync(options);
618
- console.log(result.toString());
619
- ```
620
-
621
- To examine the `result` object directly:
622
-
623
- ```js
624
- markdownlint(options, function callback(err, result) {
625
- if (!err) {
626
- console.dir(result, { "colors": true, "depth": null });
627
- }
628
- });
629
- ```
630
-
631
- Output:
632
-
633
- ```json
634
- {
635
- "good.md": [],
636
- "bad.md": [
637
- { "lineNumber": 3,
638
- "ruleNames": [ "MD010", "no-hard-tabs" ],
639
- "ruleDescription": "Hard tabs",
640
- "ruleInformation": "https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/Rules.md#md010",
641
- "errorDetail": "Column: 17",
642
- "errorContext": null,
643
- "errorRange": [ 17, 1 ] },
644
- { "lineNumber": 1,
645
- "ruleNames": [ "MD018", "no-missing-space-atx" ],
646
- "ruleDescription": "No space after hash on atx style heading",
647
- "ruleInformation": "https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/Rules.md#md018",
648
- "errorDetail": null,
649
- "errorContext": "#bad.md",
650
- "errorRange": [ 1, 2 ] },
651
- { "lineNumber": 3,
652
- "ruleNames": [ "MD018", "no-missing-space-atx" ],
653
- "ruleDescription": "No space after hash on atx style heading",
654
- "ruleInformation": "https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/Rules.md#md018",
655
- "errorDetail": null,
656
- "errorContext": "#This file fails\tsome rules.",
657
- "errorRange": [ 1, 2 ] },
658
- { "lineNumber": 1,
659
- "ruleNames": [ "MD041", "first-line-heading", "first-line-h1" ],
660
- "ruleDescription": "First line in file should be a top level heading",
661
- "ruleInformation": "https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/Rules.md#md041",
662
- "errorDetail": null,
663
- "errorContext": "#bad.md",
664
- "errorRange": null }
665
- ]
666
- }
667
- ```
668
-
669
- Integration with the [gulp](https://gulpjs.com/) build system is straightforward:
670
-
671
- ```js
672
- const gulp = require("gulp");
673
- const through2 = require("through2");
674
- const markdownlint = require("markdownlint");
675
-
676
- gulp.task("markdownlint", function task() {
677
- return gulp.src("*.md", { "read": false })
678
- .pipe(through2.obj(function obj(file, enc, next) {
679
- markdownlint(
680
- { "files": [ file.relative ] },
681
- function callback(err, result) {
682
- const resultString = (result || "").toString();
683
- if (resultString) {
684
- console.log(resultString);
685
- }
686
- next(err, file);
687
- });
688
- }));
689
- });
690
- ```
691
-
692
- Output:
693
-
694
- ```text
695
- [00:00:00] Starting 'markdownlint'...
696
- bad.md: 3: MD010/no-hard-tabs Hard tabs [Column: 17]
697
- bad.md: 1: MD018/no-missing-space-atx No space after hash on atx style heading [Context: "#bad.md"]
698
- bad.md: 3: MD018/no-missing-space-atx No space after hash on atx style heading [Context: "#This file fails some rules."]
699
- bad.md: 1: MD041/first-line-heading/first-line-h1 First line in file should be a top level heading [Context: "#bad.md"]
700
- [00:00:00] Finished 'markdownlint' after 10 ms
701
- ```
702
-
703
- Integration with the [Grunt](https://gruntjs.com/) build system is similar:
704
-
705
- ```js
706
- const markdownlint = require("markdownlint");
707
-
708
- module.exports = function wrapper(grunt) {
709
- grunt.initConfig({
710
- "markdownlint": {
711
- "example": {
712
- "src": [ "*.md" ]
713
- }
714
- }
715
- });
716
-
717
- grunt.registerMultiTask("markdownlint", function task() {
718
- const done = this.async();
719
- markdownlint(
720
- { "files": this.filesSrc },
721
- function callback(err, result) {
722
- const resultString = err || ((result || "").toString());
723
- if (resultString) {
724
- grunt.fail.warn("\n" + resultString + "\n");
725
- }
726
- done(!err || !resultString);
727
- });
728
- });
729
- };
730
- ```
731
-
732
- Output:
733
-
734
- ```text
735
- Running "markdownlint:example" (markdownlint) task
736
- Warning:
737
- bad.md: 3: MD010/no-hard-tabs Hard tabs [Column: 17]
738
- bad.md: 1: MD018/no-missing-space-atx No space after hash on atx style heading [Context: "#bad.md"]
739
- bad.md: 3: MD018/no-missing-space-atx No space after hash on atx style heading [Context: "#This file fails some rules."]
740
- bad.md: 1: MD041/first-line-heading/first-line-h1 First line in file should be a top level heading [Context: "#bad.md"]
741
- Use --force to continue.
742
- ```
743
-
744
- ## Browser
745
-
746
- `markdownlint` also works in the browser.
747
-
748
- Generate normal and minified scripts with:
749
-
750
- ```shell
751
- npm run build-demo
752
- ```
753
-
754
- Then reference `markdown-it` and `markdownlint`:
755
-
756
- ```html
757
- <script src="demo/markdown-it.min.js"></script>
758
- <script src="demo/markdownlint-browser.min.js"></script>
759
- ```
760
-
761
- And call it like so:
762
-
763
- ```js
764
- const options = {
765
- "strings": {
766
- "content": "Some Markdown to lint."
767
- }
768
- };
769
- const results = window.markdownlint.sync(options).toString();
770
- ```
771
-
772
- ## Examples
773
-
774
- For ideas how to integrate `markdownlint` into your workflow, refer to the following projects:
775
-
776
- * [.NET Documentation](https://docs.microsoft.com/en-us/dotnet/) ([Search repository](https://github.com/dotnet/docs/search?q=markdownlint))
777
- * [ally.js](https://allyjs.io/) ([Search repository](https://github.com/medialize/ally.js/search?q=markdownlint))
778
- * [Boostnote](https://boostnote.io/) ([Search repository](https://github.com/BoostIO/Boostnote/search?q=markdownlint))
779
- * [CodiMD](https://github.com/hackmdio/codimd) ([Search repository](https://github.com/hackmdio/codimd/search?q=markdownlint))
780
- * [ESLint](https://eslint.org/) ([Search repository](https://github.com/eslint/eslint/search?q=markdownlint))
781
- * [Garden React Components](https://garden.zendesk.com/react-components/) ([Search repository](https://github.com/zendeskgarden/react-components/search?q=markdownlint))
782
- * [Mocha](https://mochajs.org/) ([Search repository](https://github.com/mochajs/mocha/search?q=markdownlint))
783
- * [Reactable](https://glittershark.github.io/reactable/) ([Search repository](https://github.com/glittershark/reactable/search?q=markdownlint))
784
- * [Sinon.JS](https://sinonjs.org/) ([Search repository](https://github.com/sinonjs/sinon/search?q=markdownlint))
785
- * [TestCafe](https://devexpress.github.io/testcafe/) ([Search repository](https://github.com/DevExpress/testcafe/search?q=markdownlint))
786
- * [TypeScript Handbook](https://www.typescriptlang.org/docs/handbook/basic-types.html) ([Search repository](https://github.com/Microsoft/TypeScript-Handbook/search?q=markdownlint))
787
- * [V8](https://v8.dev/) ([Search repository](https://github.com/v8/v8.dev/search?q=markdownlint))
788
- * [webhint](https://webhint.io/) ([Search repository](https://github.com/webhintio/hint/search?q=markdownlint))
789
- * [webpack](https://webpack.js.org/) ([Search repository](https://github.com/webpack/webpack.js.org/search?q=markdownlint))
790
- * [WordPress](https://wordpress.org/gutenberg/) ([Search repository](https://github.com/WordPress/gutenberg/search?q=markdownlint))
791
-
792
- ## Contributing
793
-
794
- See [CONTRIBUTING.md](CONTRIBUTING.md) for more information.
795
-
796
- ## History
797
-
798
- * 0.0.1 - Initial release, includes tests MD001-MD032.
799
- * 0.0.2 - Improve documentation, tests, and code.
800
- * 0.0.3 - Add synchronous API, improve documentation and code.
801
- * 0.0.4 - Add tests MD033-MD040, update dependencies.
802
- * 0.0.5 - Add `strings` option to enable file-less scenarios, add in-browser demo.
803
- * 0.0.6 - Improve performance, simplify in-browser, update dependencies.
804
- * 0.0.7 - Add MD041, improve MD003, ignore front matter, update dependencies.
805
- * 0.0.8 - Support disabling/enabling rules inline, improve code fence, dependencies.
806
- * 0.1.0 - Add aliases, exceptions for MD033, exclusions for MD013, dependencies.
807
- * 0.1.1 - Fix bug handling HTML in tables, reference markdownlint-cli.
808
- * 0.2.0 - Add MD042/MD043, enhance MD002/MD003/MD004/MD007/MD011/MD025/MD041, dependencies.
809
- * 0.3.0 - More detailed error reporting with `resultVersion`, enhance MD010/MD012/MD036,
810
- fixes for MD027/MD029/MD030, include JSON schema, dependencies.
811
- * 0.3.1 - Fix regressions in MD032/MD038, update dependencies.
812
- * 0.4.0 - Add MD044, enhance MD013/MD032/MD041/MD042/MD043, fix for MD038, dependencies.
813
- * 0.4.1 - Fixes for MD038/front matter, improvements to MD044, update dependencies.
814
- * 0.5.0 - Add shareable configuration, `noInlineConfig` option, README links, fix MD030,
815
- improve MD009/MD041, update dependencies.
816
- * 0.6.0 - `resultVersion` defaults to 1 (breaking change), ignore HTML comments, TOML
817
- front matter, fixes for MD044, update dependencies.
818
- * 0.6.1 - Update `markdown-it` versioning, exclude demo/test from publishing.
819
- * 0.6.2 - Improve MD013/MD027/MD034/MD037/MD038/MD041/MD044, update dependencies.
820
- * 0.6.3 - Improve highlighting for MD020.
821
- * 0.6.4 - Improve MD029/MD042, update dependencies.
822
- * 0.7.0 - `resultVersion` defaults to 2 (breaking change), add MD045, improve MD029,
823
- remove trimLeft/trimRight, split rules, refactor, update dependencies.
824
- * 0.8.0 - Add support for using and authoring custom rules, improve MD004/MD007/MD013,
825
- add `engines` to `package.json`, refactor, update dependencies.
826
- * 0.8.1 - Update item loop to be iterative, improve MD014, update dependencies.
827
- * 0.9.0 - Remove support for end-of-life Node versions 0.10/0.12/4, change "header" to
828
- "heading" per spec (non-breaking), improve MD003/MD009/MD041, handle uncommon
829
- line-break characters, refactor for ES6, update dependencies.
830
- * 0.10.0 - Add support for non-JSON configuration files, pass file/string name to custom
831
- rules, update dependencies.
832
- * 0.11.0 - Improve MD005/MD024/MD029/MD038, improve custom rule example, add CONTRIBUTING.md,
833
- update dependencies.
834
- * 0.12.0 - Add `information` link for custom rules, `markdownItPlugins` for extensibility,
835
- improve MD023/MD032/MD038, update dependencies.
836
- * 0.13.0 - Improve MD013/MD022/MD025/MD029/MD031/MD032/MD037/MD041/, deprecate MD002,
837
- improve pandoc YAML support, update dependencies.
838
- * 0.14.0 - Remove support for end-of-life Node version 6, introduce `markdownlint-rule-helpers`,
839
- add MD046/MD047, improve MD033/MD034/MD039, improve custom rule validation and
840
- in-browser demo, update dependencies.
841
- * 0.14.1 - Improve MD033.
842
- * 0.14.2 - Improve MD047, add `handleRuleFailures` option.
843
- * 0.15.0 - Add `markdownlint-capture`/`markdownlint-restore` inline comments, improve
844
- MD009/MD013/MD026/MD033/MD036, update dependencies.
845
- * 0.16.0 - Add custom rule sample for linting code, improve MD026/MD031/MD033/MD038,
846
- update dependencies.
847
- * 0.17.0 - Add `resultVersion` 3 to support fix information for default and custom rules,
848
- add fix information for 24 rules, update newline handling to match latest
849
- CommonMark specification, improve MD014/MD037/MD039, update dependencies.
850
- * 0.17.1 - Fix handling of front matter by fix information.
851
- * 0.17.2 - Improve MD020/MD033/MD044.
852
- * 0.18.0 - Add MD048/code-fence-style, add fix information for MD007/ul-indent, add
853
- `markdownlint-disable-file`/`markdownlint-enable-file` inline comments, add
854
- type declaration file (.d.ts) for TypeScript dependents, update schema, improve
855
- MD006/MD007/MD009/MD013/MD030, update dependencies.
856
- * 0.19.0 - Remove support for end-of-life Node version 8, add fix information for
857
- MD005/list-indent, improve MD007/MD013/MD014, deprecate MD006/ul-start-left, add
858
- rationale for every rule, update test runner and code coverage, add more JSDoc
859
- comments, update dependencies.
860
- * 0.20.0 - Add `markdownlint-configure-file` inline comment,
861
- improve MD005/MD007/MD013/MD018/MD029/MD031/MD034/MD037/MD038/MD039, improve HTML
862
- comment handling, update dependencies.
863
- * 0.20.1 - Fix regression in MD037.
864
- * 0.20.2 - Fix regression in MD037, improve MD038.
865
-
866
- [npm-image]: https://img.shields.io/npm/v/markdownlint.svg
867
- [npm-url]: https://www.npmjs.com/package/markdownlint
868
- [ci-image]: https://github.com/DavidAnson/markdownlint/workflows/CI/badge.svg?branch=master
869
- [ci-url]: https://github.com/DavidAnson/markdownlint/actions?query=branch%3Amaster
870
- [license-image]: https://img.shields.io/npm/l/markdownlint.svg
871
- [license-url]: https://opensource.org/licenses/MIT
1
+ # markdownlint
2
+
3
+ > A Node.js style checker and lint tool for Markdown/CommonMark files.
4
+
5
+ [![npm version][npm-image]][npm-url]
6
+ [![CI Status][ci-image]][ci-url]
7
+ [![License][license-image]][license-url]
8
+
9
+ ## Install
10
+
11
+ ```shell
12
+ npm install markdownlint --save-dev
13
+ ```
14
+
15
+ ## Overview
16
+
17
+ The [Markdown](https://en.wikipedia.org/wiki/Markdown) markup language is
18
+ designed to be easy to read, write, and understand. It succeeds - and its
19
+ flexibility is both a benefit and a drawback. Many styles are possible, so
20
+ formatting can be inconsistent. Some constructs don't work well in all
21
+ parsers and should be avoided. The [CommonMark](https://commonmark.org/)
22
+ specification standardizes parsers - but not authors.
23
+
24
+ `markdownlint` is a
25
+ [static analysis](https://en.wikipedia.org/wiki/Static_program_analysis)
26
+ tool for [Node.js](https://nodejs.org/) with a library of rules
27
+ to enforce standards and consistency for Markdown files. It was
28
+ inspired by - and heavily influenced by - Mark Harrison's
29
+ [markdownlint](https://github.com/markdownlint/markdownlint) for
30
+ [Ruby](https://www.ruby-lang.org/). The initial rules, rule documentation,
31
+ and test cases came directly from that project.
32
+
33
+ ### Related
34
+
35
+ * CLI
36
+ * [markdownlint-cli command-line interface for Node.js](https://github.com/igorshubovych/markdownlint-cli)
37
+ * [markdownlint-cli2 command-line interface for Node.js](https://github.com/DavidAnson/markdownlint-cli2)
38
+ * GitHub
39
+ * [GitHub Super-Linter Action](https://github.com/github/super-linter)
40
+ * [GitHub Actions problem matcher for markdownlint-cli](https://github.com/xt0rted/markdownlint-problem-matcher)
41
+ * Editor
42
+ * [vscode-markdownlint extension for VS Code](https://marketplace.visualstudio.com/items/DavidAnson.vscode-markdownlint)
43
+ * [Sublime Text markdownlint for Sublime Text](https://packagecontrol.io/packages/SublimeLinter-contrib-markdownlint)
44
+ * [linter-node-markdownlint extension for Atom](https://atom.io/packages/linter-node-markdownlint)
45
+ * [coc-markdownlint extension for Vim/Neovim](https://github.com/fannheyward/coc-markdownlint)
46
+ * Tooling
47
+ * [grunt-markdownlint for the Grunt task runner](https://github.com/sagiegurari/grunt-markdownlint)
48
+ * [Cake.Markdownlint addin for Cake build automation system](https://github.com/cake-contrib/Cake.Markdownlint)
49
+ * Ruby
50
+ * [markdownlint/mdl gem for Ruby](https://rubygems.org/gems/mdl)
51
+
52
+ ## Demonstration
53
+
54
+ [`markdownlint` demo](https://dlaa.me/markdownlint/), an interactive, in-browser
55
+ playground for learning and exploring.
56
+
57
+ ## Rules / Aliases
58
+
59
+ * **[MD001](doc/Rules.md#md001)** *heading-increment/header-increment* - Heading levels should only increment by one level at a time
60
+ * ~~**[MD002](doc/Rules.md#md002)** *first-heading-h1/first-header-h1* - First heading should be a top level heading~~
61
+ * **[MD003](doc/Rules.md#md003)** *heading-style/header-style* - Heading style
62
+ * **[MD004](doc/Rules.md#md004)** *ul-style* - Unordered list style
63
+ * **[MD005](doc/Rules.md#md005)** *list-indent* - Inconsistent indentation for list items at the same level
64
+ * ~~**[MD006](doc/Rules.md#md006)** *ul-start-left* - Consider starting bulleted lists at the beginning of the line~~
65
+ * **[MD007](doc/Rules.md#md007)** *ul-indent* - Unordered list indentation
66
+ * **[MD009](doc/Rules.md#md009)** *no-trailing-spaces* - Trailing spaces
67
+ * **[MD010](doc/Rules.md#md010)** *no-hard-tabs* - Hard tabs
68
+ * **[MD011](doc/Rules.md#md011)** *no-reversed-links* - Reversed link syntax
69
+ * **[MD012](doc/Rules.md#md012)** *no-multiple-blanks* - Multiple consecutive blank lines
70
+ * **[MD013](doc/Rules.md#md013)** *line-length* - Line length
71
+ * **[MD014](doc/Rules.md#md014)** *commands-show-output* - Dollar signs used before commands without showing output
72
+ * **[MD018](doc/Rules.md#md018)** *no-missing-space-atx* - No space after hash on atx style heading
73
+ * **[MD019](doc/Rules.md#md019)** *no-multiple-space-atx* - Multiple spaces after hash on atx style heading
74
+ * **[MD020](doc/Rules.md#md020)** *no-missing-space-closed-atx* - No space inside hashes on closed atx style heading
75
+ * **[MD021](doc/Rules.md#md021)** *no-multiple-space-closed-atx* - Multiple spaces inside hashes on closed atx style heading
76
+ * **[MD022](doc/Rules.md#md022)** *blanks-around-headings/blanks-around-headers* - Headings should be surrounded by blank lines
77
+ * **[MD023](doc/Rules.md#md023)** *heading-start-left/header-start-left* - Headings must start at the beginning of the line
78
+ * **[MD024](doc/Rules.md#md024)** *no-duplicate-heading/no-duplicate-header* - Multiple headings with the same content
79
+ * **[MD025](doc/Rules.md#md025)** *single-title/single-h1* - Multiple top level headings in the same document
80
+ * **[MD026](doc/Rules.md#md026)** *no-trailing-punctuation* - Trailing punctuation in heading
81
+ * **[MD027](doc/Rules.md#md027)** *no-multiple-space-blockquote* - Multiple spaces after blockquote symbol
82
+ * **[MD028](doc/Rules.md#md028)** *no-blanks-blockquote* - Blank line inside blockquote
83
+ * **[MD029](doc/Rules.md#md029)** *ol-prefix* - Ordered list item prefix
84
+ * **[MD030](doc/Rules.md#md030)** *list-marker-space* - Spaces after list markers
85
+ * **[MD031](doc/Rules.md#md031)** *blanks-around-fences* - Fenced code blocks should be surrounded by blank lines
86
+ * **[MD032](doc/Rules.md#md032)** *blanks-around-lists* - Lists should be surrounded by blank lines
87
+ * **[MD033](doc/Rules.md#md033)** *no-inline-html* - Inline HTML
88
+ * **[MD034](doc/Rules.md#md034)** *no-bare-urls* - Bare URL used
89
+ * **[MD035](doc/Rules.md#md035)** *hr-style* - Horizontal rule style
90
+ * **[MD036](doc/Rules.md#md036)** *no-emphasis-as-heading/no-emphasis-as-header* - Emphasis used instead of a heading
91
+ * **[MD037](doc/Rules.md#md037)** *no-space-in-emphasis* - Spaces inside emphasis markers
92
+ * **[MD038](doc/Rules.md#md038)** *no-space-in-code* - Spaces inside code span elements
93
+ * **[MD039](doc/Rules.md#md039)** *no-space-in-links* - Spaces inside link text
94
+ * **[MD040](doc/Rules.md#md040)** *fenced-code-language* - Fenced code blocks should have a language specified
95
+ * **[MD041](doc/Rules.md#md041)** *first-line-heading/first-line-h1* - First line in file should be a top level heading
96
+ * **[MD042](doc/Rules.md#md042)** *no-empty-links* - No empty links
97
+ * **[MD043](doc/Rules.md#md043)** *required-headings/required-headers* - Required heading structure
98
+ * **[MD044](doc/Rules.md#md044)** *proper-names* - Proper names should have the correct capitalization
99
+ * **[MD045](doc/Rules.md#md045)** *no-alt-text* - Images should have alternate text (alt text)
100
+ * **[MD046](doc/Rules.md#md046)** *code-block-style* - Code block style
101
+ * **[MD047](doc/Rules.md#md047)** *single-trailing-newline* - Files should end with a single newline character
102
+ * **[MD048](doc/Rules.md#md048)** *code-fence-style* - Code fence style
103
+
104
+ See [Rules.md](doc/Rules.md) for more details.
105
+
106
+ ~~Struck through~~ rules are deprecated, and provided for backward-compatibility.
107
+
108
+ > All rules with `heading` as part of their name are also available as `header`
109
+ > aliases (e.g. `heading-increment` is also available as `header-increment`).
110
+ > The use of `header` is deprecated and provided for backward-compatibility.
111
+
112
+ ## Tags
113
+
114
+ Tags group related rules and can be used to enable/disable multiple rules at once.
115
+
116
+ * **accessibility** - MD045
117
+ * **atx** - MD018, MD019
118
+ * **atx_closed** - MD020, MD021
119
+ * **blank_lines** - MD012, MD022, MD031, MD032, MD047
120
+ * **blockquote** - MD027, MD028
121
+ * **bullet** - MD004, MD005, MD006, MD007, MD032
122
+ * **code** - MD014, MD031, MD038, MD040, MD046, MD048
123
+ * **emphasis** - MD036, MD037
124
+ * **hard_tab** - MD010
125
+ * **headers** - MD001, MD002, MD003, MD018, MD019, MD020, MD021, MD022, MD023,
126
+ MD024, MD025, MD026, MD036, MD041, MD043
127
+ * **headings** - MD001, MD002, MD003, MD018, MD019, MD020, MD021, MD022, MD023,
128
+ MD024, MD025, MD026, MD036, MD041, MD043
129
+ * **hr** - MD035
130
+ * **html** - MD033
131
+ * **images** - MD045
132
+ * **indentation** - MD005, MD006, MD007, MD027
133
+ * **language** - MD040
134
+ * **line_length** - MD013
135
+ * **links** - MD011, MD034, MD039, MD042
136
+ * **ol** - MD029, MD030, MD032
137
+ * **spaces** - MD018, MD019, MD020, MD021, MD023
138
+ * **spelling** - MD044
139
+ * **ul** - MD004, MD005, MD006, MD007, MD030, MD032
140
+ * **url** - MD034
141
+ * **whitespace** - MD009, MD010, MD012, MD027, MD028, MD030, MD037, MD038, MD039
142
+
143
+ ## Configuration
144
+
145
+ Text passed to `markdownlint` is parsed as Markdown, analyzed, and any issues reported.
146
+ Two kinds of text are ignored:
147
+
148
+ * [HTML comments](https://www.w3.org/TR/html5/syntax.html#comments)
149
+ * [Front matter](https://jekyllrb.com/docs/frontmatter/) (see `options.frontMatter` below)
150
+
151
+ Rules can be enabled, disabled, and configured via `options.config` (described
152
+ below) to define the expected behavior for a set of inputs. To enable or disable
153
+ rules at a particular location within a file, add one of these markers to the
154
+ appropriate place (HTML comments don't appear in the final markup):
155
+
156
+ * Disable all rules: `<!-- markdownlint-disable -->`
157
+ * Enable all rules: `<!-- markdownlint-enable -->`
158
+ * Disable one or more rules by name: `<!-- markdownlint-disable MD001 MD005 -->`
159
+ * Enable one or more rules by name: `<!-- markdownlint-enable MD001 MD005 -->`
160
+ * Capture the current rule configuration: `<!-- markdownlint-capture -->`
161
+ * Restore the captured rule configuration: `<!-- markdownlint-restore -->`
162
+
163
+ For example:
164
+
165
+ ```markdown
166
+ <!-- markdownlint-disable no-space-in-emphasis -->
167
+ deliberate space * in * emphasis
168
+ <!-- markdownlint-enable no-space-in-emphasis -->
169
+ ```
170
+
171
+ To temporarily disable rule(s), then restore the former configuration:
172
+
173
+ ```markdown
174
+ <!-- markdownlint-capture -->
175
+ <!-- markdownlint-disable -->
176
+ any violations you want
177
+ <!-- markdownlint-restore -->
178
+ ```
179
+
180
+ The initial configuration is captured by default (as if every document began
181
+ with `<!-- markdownlint-capture -->`), so the pattern above can be expressed
182
+ more simply:
183
+
184
+ ```markdown
185
+ <!-- markdownlint-disable -->
186
+ any violations you want
187
+ <!-- markdownlint-restore -->
188
+ ```
189
+
190
+ Changes take effect starting with the line a comment is on, so the following
191
+ has no effect:
192
+
193
+ ```markdown
194
+ space * in * emphasis <!-- markdownlint-disable --> <!-- markdownlint-enable -->
195
+ ```
196
+
197
+ To apply changes to an entire file regardless of where the comment is located,
198
+ the following syntax is supported:
199
+
200
+ * Disable all rules: `<!-- markdownlint-disable-file -->`
201
+ * Enable all rules: `<!-- markdownlint-enable-file -->`
202
+ * Disable one or more rules by name: `<!-- markdownlint-disable-file MD001 -->`
203
+ * Enable one or more rules by name: `<!-- markdownlint-enable-file MD001 -->`
204
+
205
+ This can be used to "hide" `markdownlint` comments at the bottom of a file.
206
+
207
+ In cases where it is desirable to change the configuration of one or more rules
208
+ for a file, the following more advanced syntax is supported:
209
+
210
+ * Configure: `<!-- markdownlint-configure-file { options.config JSON } -->`
211
+
212
+ For example:
213
+
214
+ ```markdown
215
+ <!-- markdownlint-configure-file { "MD013": { "line_length": 70 } } -->
216
+ ```
217
+
218
+ or
219
+
220
+ ```markdown
221
+ <!-- markdownlint-configure-file
222
+ {
223
+ "hr-style": {
224
+ "style": "---"
225
+ },
226
+ "no-trailing-spaces": false
227
+ }
228
+ -->
229
+ ```
230
+
231
+ These changes apply to the entire file regardless of where the comment is
232
+ located. Multiple such comments (if present) are applied top-to-bottom.
233
+
234
+ ## API
235
+
236
+ ### Linting
237
+
238
+ Standard asynchronous API:
239
+
240
+ ```js
241
+ /**
242
+ * Lint specified Markdown files.
243
+ *
244
+ * @param {Options} options Configuration options.
245
+ * @param {LintCallback} callback Callback (err, result) function.
246
+ * @returns {void}
247
+ */
248
+ function markdownlint(options, callback) { ... }
249
+ ```
250
+
251
+ Synchronous API (for build scripts, etc.):
252
+
253
+ ```js
254
+ /**
255
+ * Lint specified Markdown files synchronously.
256
+ *
257
+ * @param {Options} options Configuration options.
258
+ * @returns {LintResults} Results object.
259
+ */
260
+ function markdownlint.sync(options) { ... }
261
+ ```
262
+
263
+ Promise API (in the `promises` namespace like Node.js's
264
+ [`fs` Promises API](https://nodejs.org/api/fs.html#fs_fs_promises_api)):
265
+
266
+ ```js
267
+ /**
268
+ * Lint specified Markdown files.
269
+ *
270
+ * @param {Options} options Configuration options.
271
+ * @returns {Promise<LintResults>} Results object.
272
+ */
273
+ function markdownlint(options) { ... }
274
+ ```
275
+
276
+ #### options
277
+
278
+ Type: `Object`
279
+
280
+ Configures the function.
281
+
282
+ ##### options.customRules
283
+
284
+ Type: `Array` of `Object`
285
+
286
+ List of custom rules to include with the default rule set for linting.
287
+
288
+ Each array element should define a rule. Rules are typically exported by another
289
+ package, but can be defined locally. Custom rules are identified by the
290
+ [keyword `markdownlint-rule` on npm](https://www.npmjs.com/search?q=keywords:markdownlint-rule).
291
+
292
+ Example:
293
+
294
+ ```js
295
+ const extraRules = require("extraRules");
296
+ const options = {
297
+ "customRules": [ extraRules.one, extraRules.two ]
298
+ };
299
+ ```
300
+
301
+ See [CustomRules.md](doc/CustomRules.md) for details about authoring custom rules.
302
+
303
+ ##### options.files
304
+
305
+ Type: `Array` of `String`
306
+
307
+ List of files to lint.
308
+
309
+ Each array element should be a single file (via relative or absolute path);
310
+ [globbing](https://en.wikipedia.org/wiki/Glob_%28programming%29) is the caller's
311
+ responsibility.
312
+
313
+ Example: `[ "one.md", "dir/two.md" ]`
314
+
315
+ ##### options.strings
316
+
317
+ Type: `Object` mapping `String` to `String`
318
+
319
+ Map of identifiers to strings for linting.
320
+
321
+ When Markdown content is not available as files, it can be passed as strings.
322
+ The keys of the `strings` object are used to identify each input value in the
323
+ `result` summary.
324
+
325
+ Example:
326
+
327
+ ```json
328
+ {
329
+ "readme": "# README\n...",
330
+ "changelog": "# CHANGELOG\n..."
331
+ }
332
+ ```
333
+
334
+ ##### options.config
335
+
336
+ Type: `Object` mapping `String` to `Boolean | Object`
337
+
338
+ Configures the rules to use.
339
+
340
+ Object keys are rule names or aliases and values are the rule's configuration.
341
+ The value `false` disables a rule, `true` enables its default configuration,
342
+ and passing an object customizes its settings. Setting the special `default`
343
+ rule to `true` or `false` includes/excludes all rules by default. Enabling or
344
+ disabling a tag name (ex: `whitespace`) affects all rules having that tag.
345
+
346
+ The `default` rule is applied first, then keys are processed in order from top
347
+ to bottom with later values overriding earlier ones. Keys (including rule names,
348
+ aliases, tags, and `default`) are not case-sensitive.
349
+
350
+ Example:
351
+
352
+ ```json
353
+ {
354
+ "default": true,
355
+ "MD003": { "style": "atx_closed" },
356
+ "MD007": { "indent": 4 },
357
+ "no-hard-tabs": false,
358
+ "whitespace": false
359
+ }
360
+ ```
361
+
362
+ Sets of rules (known as a "style") can be stored separately and loaded as
363
+ [JSON](https://en.wikipedia.org/wiki/JSON).
364
+
365
+ Example:
366
+
367
+ ```js
368
+ const options = {
369
+ "files": [ "..." ],
370
+ "config": require("style/relaxed.json")
371
+ };
372
+ ```
373
+
374
+ See the [style](style) directory for more samples.
375
+
376
+ See [markdownlint-config-schema.json](schema/markdownlint-config-schema.json)
377
+ for the [JSON Schema](https://json-schema.org/) of the `options.config` object.
378
+
379
+ For more advanced scenarios, styles can reference and extend other styles. The
380
+ `readConfig` and `readConfigSync` functions can be used to read such styles.
381
+
382
+ For example, assuming a `base.json` configuration file:
383
+
384
+ ```json
385
+ {
386
+ "default": true
387
+ }
388
+ ```
389
+
390
+ And a `custom.json` configuration file:
391
+
392
+ ```json
393
+ {
394
+ "extends": "base.json",
395
+ "line-length": false
396
+ }
397
+ ```
398
+
399
+ Then code like the following:
400
+
401
+ ```js
402
+ const options = {
403
+ "config": markdownlint.readConfigSync("./custom.json")
404
+ };
405
+ ```
406
+
407
+ Merges `custom.json` and `base.json` and is equivalent to:
408
+
409
+ ```js
410
+ const options = {
411
+ "config": {
412
+ "default": true,
413
+ "line-length": false
414
+ }
415
+ };
416
+ ```
417
+
418
+ ##### options.frontMatter
419
+
420
+ Type: `RegExp`
421
+
422
+ Matches any [front matter](https://jekyllrb.com/docs/frontmatter/) found at the
423
+ beginning of a file.
424
+
425
+ Some Markdown content begins with metadata; the default `RegExp` for this option
426
+ ignores common forms of "front matter". To match differently, specify a custom
427
+ `RegExp` or use the value `null` to disable the feature.
428
+
429
+ The default value:
430
+
431
+ ```js
432
+ /((^---\s*$[^]*?^---\s*$)|(^\+\+\+\s*$[^]*?^(\+\+\+|\.\.\.)\s*$))(\r\n|\r|\n|$)/m
433
+ ```
434
+
435
+ Ignores [YAML](https://en.wikipedia.org/wiki/YAML) and
436
+ [TOML](https://en.wikipedia.org/wiki/TOML) such as:
437
+
438
+ ```text
439
+ ---
440
+ layout: post
441
+ title: Title
442
+ ---
443
+ ```
444
+
445
+ Note: Matches must occur at the start of the file.
446
+
447
+ ##### options.handleRuleFailures
448
+
449
+ Type: `Boolean`
450
+
451
+ Catches exceptions thrown during rule processing and reports the problem as a
452
+ rule violation.
453
+
454
+ By default, exceptions thrown by rules (or the library itself) are unhandled
455
+ and bubble up the stack to the caller in the conventional manner. By setting
456
+ `handleRuleFailures` to `true`, exceptions thrown by failing rules will be
457
+ handled by the library and the exception message logged as a rule violation.
458
+ This setting can be useful in the presence of (custom) rules that encounter
459
+ unexpected syntax and fail. By enabling this option, the linting process is
460
+ allowed to continue and report any violations that were found.
461
+
462
+ ##### options.noInlineConfig
463
+
464
+ Type: `Boolean`
465
+
466
+ Disables the use of HTML comments like `<!-- markdownlint-disable -->` to toggle
467
+ rules within the body of Markdown content.
468
+
469
+ By default, properly-formatted inline comments can be used to create exceptions
470
+ for parts of a document. Setting `noInlineConfig` to `true` ignores all such
471
+ comments.
472
+
473
+ ##### options.resultVersion
474
+
475
+ Type: `Number`
476
+
477
+ Specifies which version of the `result` object to return (see the "Usage" section
478
+ below for examples).
479
+
480
+ Passing a `resultVersion` of `0` corresponds to the original, simple format where
481
+ each error is identified by rule name and line number. *This is deprecated.*
482
+
483
+ Passing a `resultVersion` of `1` corresponds to a detailed format where each error
484
+ includes information about the line number, rule name, alias, description, as well
485
+ as any additional detail or context that is available. *This is deprecated.*
486
+
487
+ Passing a `resultVersion` of `2` corresponds to a detailed format where each error
488
+ includes information about the line number, rule names, description, as well as any
489
+ additional detail or context that is available. *This is the default.*
490
+
491
+ Passing a `resultVersion` of `3` corresponds to the detailed version `2` format
492
+ with additional information about how to fix automatically-fixable errors. In this
493
+ mode, all errors that occur on each line are reported (other versions report only
494
+ the first error for each rule).
495
+
496
+ ##### options.markdownItPlugins
497
+
498
+ Type: `Array` of `Array` of `Function` and plugin parameters
499
+
500
+ Specifies additional [markdown-it plugins](https://www.npmjs.com/search?q=keywords:markdown-it-plugin)
501
+ to use when parsing input. Plugins can be used to support additional syntax and
502
+ features for advanced scenarios.
503
+
504
+ Each item in the top-level `Array` should be of the form:
505
+
506
+ ```js
507
+ [ require("markdown-it-plugin"), plugin_param_0, plugin_param_1, ... ]
508
+ ```
509
+
510
+ #### callback
511
+
512
+ Type: `Function` taking (`Error`, `Object`)
513
+
514
+ Standard completion callback.
515
+
516
+ #### result
517
+
518
+ Type: `Object`
519
+
520
+ Call `result.toString()` for convenience or see below for an example of the
521
+ structure of the `result` object. Passing the value `true` to `toString()`
522
+ uses rule aliases (ex: `no-hard-tabs`) instead of names (ex: `MD010`).
523
+
524
+ ### Config
525
+
526
+ The `options.config` configuration object is simple and can be stored in a file
527
+ for readability and easy reuse. The `readConfig` and `readConfigSync` functions
528
+ load configuration settings and support the `extends` keyword for referencing
529
+ other files (see above).
530
+
531
+ By default, configuration files are parsed as JSON (and named `.markdownlint.json`).
532
+ Custom parsers can be provided to handle other formats like JSONC, YAML, and TOML.
533
+
534
+ Asynchronous API:
535
+
536
+ ```js
537
+ /**
538
+ * Read specified configuration file.
539
+ *
540
+ * @param {string} file Configuration file name.
541
+ * @param {ConfigurationParser[] | ReadConfigCallback} parsers Parsing function(s).
542
+ * @param {ReadConfigCallback} [callback] Callback (err, result) function.
543
+ * @returns {void}
544
+ */
545
+ function readConfig(file, parsers, callback) { ... }
546
+ ```
547
+
548
+ Synchronous API:
549
+
550
+ ```js
551
+ /**
552
+ * Read specified configuration file synchronously.
553
+ *
554
+ * @param {string} file Configuration file name.
555
+ * @param {ConfigurationParser[]} [parsers] Parsing function(s).
556
+ * @returns {Configuration} Configuration object.
557
+ */
558
+ function readConfigSync(file, parsers) { ... }
559
+ ```
560
+
561
+ Promise API (in the `promises` namespace like Node.js's
562
+ [`fs` Promises API](https://nodejs.org/api/fs.html#fs_fs_promises_api)):
563
+
564
+ ```js
565
+ /**
566
+ * Read specified configuration file.
567
+ *
568
+ * @param {string} file Configuration file name.
569
+ * @param {ConfigurationParser[]} [parsers] Parsing function(s).
570
+ * @returns {Promise<Configuration>} Configuration object.
571
+ */
572
+ function readConfig(file, parsers) { ... }
573
+ ```
574
+
575
+ #### file
576
+
577
+ Type: `String`
578
+
579
+ Location of configuration file to read.
580
+
581
+ The `file` is resolved relative to the current working directory. If an `extends`
582
+ key is present once read, its value will be resolved as a path relative to `file`
583
+ and loaded recursively. Settings from a file referenced by `extends` are applied
584
+ first, then those of `file` are applied on top (overriding any of the same keys
585
+ appearing in the referenced file).
586
+
587
+ #### parsers
588
+
589
+ Type: *Optional* `Array` of `Function` taking (`String`) and returning `Object`
590
+
591
+ Array of functions to parse configuration files.
592
+
593
+ The contents of a configuration file are passed to each parser function until one
594
+ of them returns a value (vs. throwing an exception). Consequently, strict parsers
595
+ should come before flexible parsers.
596
+
597
+ For example:
598
+
599
+ ```js
600
+ [ JSON.parse, require("toml").parse, require("js-yaml").safeLoad ]
601
+ ```
602
+
603
+ #### callback
604
+
605
+ Type: `Function` taking (`Error`, `Object`)
606
+
607
+ Standard completion callback.
608
+
609
+ #### result
610
+
611
+ Type: `Object`
612
+
613
+ Configuration object.
614
+
615
+ ## Usage
616
+
617
+ Invoke `markdownlint` and use the `result` object's `toString` method:
618
+
619
+ ```js
620
+ const markdownlint = require("markdownlint");
621
+
622
+ const options = {
623
+ "files": [ "good.md", "bad.md" ],
624
+ "strings": {
625
+ "good.string": "# good.string\n\nThis string passes all rules.",
626
+ "bad.string": "#bad.string\n\n#This string fails\tsome rules."
627
+ }
628
+ };
629
+
630
+ markdownlint(options, function callback(err, result) {
631
+ if (!err) {
632
+ console.log(result.toString());
633
+ }
634
+ });
635
+ ```
636
+
637
+ Output:
638
+
639
+ ```text
640
+ bad.string: 3: MD010/no-hard-tabs Hard tabs [Column: 19]
641
+ bad.string: 1: MD018/no-missing-space-atx No space after hash on atx style heading [Context: "#bad.string"]
642
+ bad.string: 3: MD018/no-missing-space-atx No space after hash on atx style heading [Context: "#This string fails some rules."]
643
+ bad.string: 1: MD041/first-line-heading/first-line-h1 First line in file should be a top level heading [Context: "#bad.string"]
644
+ bad.md: 3: MD010/no-hard-tabs Hard tabs [Column: 17]
645
+ bad.md: 1: MD018/no-missing-space-atx No space after hash on atx style heading [Context: "#bad.md"]
646
+ bad.md: 3: MD018/no-missing-space-atx No space after hash on atx style heading [Context: "#This file fails some rules."]
647
+ bad.md: 1: MD041/first-line-heading/first-line-h1 First line in file should be a top level heading [Context: "#bad.md"]
648
+ ```
649
+
650
+ Or invoke `markdownlint.sync` for a synchronous call:
651
+
652
+ ```js
653
+ const result = markdownlint.sync(options);
654
+ console.log(result.toString());
655
+ ```
656
+
657
+ To examine the `result` object directly:
658
+
659
+ ```js
660
+ markdownlint(options, function callback(err, result) {
661
+ if (!err) {
662
+ console.dir(result, { "colors": true, "depth": null });
663
+ }
664
+ });
665
+ ```
666
+
667
+ Output:
668
+
669
+ ```json
670
+ {
671
+ "good.md": [],
672
+ "bad.md": [
673
+ { "lineNumber": 3,
674
+ "ruleNames": [ "MD010", "no-hard-tabs" ],
675
+ "ruleDescription": "Hard tabs",
676
+ "ruleInformation": "https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/Rules.md#md010",
677
+ "errorDetail": "Column: 17",
678
+ "errorContext": null,
679
+ "errorRange": [ 17, 1 ] },
680
+ { "lineNumber": 1,
681
+ "ruleNames": [ "MD018", "no-missing-space-atx" ],
682
+ "ruleDescription": "No space after hash on atx style heading",
683
+ "ruleInformation": "https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/Rules.md#md018",
684
+ "errorDetail": null,
685
+ "errorContext": "#bad.md",
686
+ "errorRange": [ 1, 2 ] },
687
+ { "lineNumber": 3,
688
+ "ruleNames": [ "MD018", "no-missing-space-atx" ],
689
+ "ruleDescription": "No space after hash on atx style heading",
690
+ "ruleInformation": "https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/Rules.md#md018",
691
+ "errorDetail": null,
692
+ "errorContext": "#This file fails\tsome rules.",
693
+ "errorRange": [ 1, 2 ] },
694
+ { "lineNumber": 1,
695
+ "ruleNames": [ "MD041", "first-line-heading", "first-line-h1" ],
696
+ "ruleDescription": "First line in file should be a top level heading",
697
+ "ruleInformation": "https://github.com/DavidAnson/markdownlint/blob/v0.0.0/doc/Rules.md#md041",
698
+ "errorDetail": null,
699
+ "errorContext": "#bad.md",
700
+ "errorRange": null }
701
+ ]
702
+ }
703
+ ```
704
+
705
+ Integration with the [gulp](https://gulpjs.com/) build system is straightforward:
706
+
707
+ ```js
708
+ const gulp = require("gulp");
709
+ const through2 = require("through2");
710
+ const markdownlint = require("markdownlint");
711
+
712
+ gulp.task("markdownlint", function task() {
713
+ return gulp.src("*.md", { "read": false })
714
+ .pipe(through2.obj(function obj(file, enc, next) {
715
+ markdownlint(
716
+ { "files": [ file.relative ] },
717
+ function callback(err, result) {
718
+ const resultString = (result || "").toString();
719
+ if (resultString) {
720
+ console.log(resultString);
721
+ }
722
+ next(err, file);
723
+ });
724
+ }));
725
+ });
726
+ ```
727
+
728
+ Output:
729
+
730
+ ```text
731
+ [00:00:00] Starting 'markdownlint'...
732
+ bad.md: 3: MD010/no-hard-tabs Hard tabs [Column: 17]
733
+ bad.md: 1: MD018/no-missing-space-atx No space after hash on atx style heading [Context: "#bad.md"]
734
+ bad.md: 3: MD018/no-missing-space-atx No space after hash on atx style heading [Context: "#This file fails some rules."]
735
+ bad.md: 1: MD041/first-line-heading/first-line-h1 First line in file should be a top level heading [Context: "#bad.md"]
736
+ [00:00:00] Finished 'markdownlint' after 10 ms
737
+ ```
738
+
739
+ Integration with the [Grunt](https://gruntjs.com/) build system is similar:
740
+
741
+ ```js
742
+ const markdownlint = require("markdownlint");
743
+
744
+ module.exports = function wrapper(grunt) {
745
+ grunt.initConfig({
746
+ "markdownlint": {
747
+ "example": {
748
+ "src": [ "*.md" ]
749
+ }
750
+ }
751
+ });
752
+
753
+ grunt.registerMultiTask("markdownlint", function task() {
754
+ const done = this.async();
755
+ markdownlint(
756
+ { "files": this.filesSrc },
757
+ function callback(err, result) {
758
+ const resultString = err || ((result || "").toString());
759
+ if (resultString) {
760
+ grunt.fail.warn("\n" + resultString + "\n");
761
+ }
762
+ done(!err || !resultString);
763
+ });
764
+ });
765
+ };
766
+ ```
767
+
768
+ Output:
769
+
770
+ ```text
771
+ Running "markdownlint:example" (markdownlint) task
772
+ Warning:
773
+ bad.md: 3: MD010/no-hard-tabs Hard tabs [Column: 17]
774
+ bad.md: 1: MD018/no-missing-space-atx No space after hash on atx style heading [Context: "#bad.md"]
775
+ bad.md: 3: MD018/no-missing-space-atx No space after hash on atx style heading [Context: "#This file fails some rules."]
776
+ bad.md: 1: MD041/first-line-heading/first-line-h1 First line in file should be a top level heading [Context: "#bad.md"]
777
+ Use --force to continue.
778
+ ```
779
+
780
+ ## Browser
781
+
782
+ `markdownlint` also works in the browser.
783
+
784
+ Generate normal and minified scripts with:
785
+
786
+ ```shell
787
+ npm run build-demo
788
+ ```
789
+
790
+ Then reference `markdown-it` and `markdownlint`:
791
+
792
+ ```html
793
+ <script src="demo/markdown-it.min.js"></script>
794
+ <script src="demo/markdownlint-browser.min.js"></script>
795
+ ```
796
+
797
+ And call it like so:
798
+
799
+ ```js
800
+ const options = {
801
+ "strings": {
802
+ "content": "Some Markdown to lint."
803
+ }
804
+ };
805
+ const results = window.markdownlint.sync(options).toString();
806
+ ```
807
+
808
+ ## Examples
809
+
810
+ For ideas how to integrate `markdownlint` into your workflow, refer to the following projects:
811
+
812
+ * [.NET Documentation](https://docs.microsoft.com/en-us/dotnet/) ([Search repository](https://github.com/dotnet/docs/search?q=markdownlint))
813
+ * [ally.js](https://allyjs.io/) ([Search repository](https://github.com/medialize/ally.js/search?q=markdownlint))
814
+ * [Boostnote](https://boostnote.io/) ([Search repository](https://github.com/BoostIO/Boostnote/search?q=markdownlint))
815
+ * [CodiMD](https://github.com/hackmdio/codimd) ([Search repository](https://github.com/hackmdio/codimd/search?q=markdownlint))
816
+ * [ESLint](https://eslint.org/) ([Search repository](https://github.com/eslint/eslint/search?q=markdownlint))
817
+ * [Garden React Components](https://zendeskgarden.github.io/react-components/) ([Search repository](https://github.com/zendeskgarden/react-components/search?q=markdownlint))
818
+ * [MkDocs](https://www.mkdocs.org/) ([Search repository](https://github.com/mkdocs/mkdocs/search?q=markdownlint))
819
+ * [Mocha](https://mochajs.org/) ([Search repository](https://github.com/mochajs/mocha/search?q=markdownlint))
820
+ * [Reactable](https://glittershark.github.io/reactable/) ([Search repository](https://github.com/glittershark/reactable/search?q=markdownlint))
821
+ * [Sinon.JS](https://sinonjs.org/) ([Search repository](https://github.com/sinonjs/sinon/search?q=markdownlint))
822
+ * [TestCafe](https://devexpress.github.io/testcafe/) ([Search repository](https://github.com/DevExpress/testcafe/search?q=markdownlint))
823
+ * [TypeScript Handbook](https://www.typescriptlang.org/docs/handbook/basic-types.html) ([Search repository](https://github.com/Microsoft/TypeScript-Handbook/search?q=markdownlint))
824
+ * [V8](https://v8.dev/) ([Search repository](https://github.com/v8/v8.dev/search?q=markdownlint))
825
+ * [webhint](https://webhint.io/) ([Search repository](https://github.com/webhintio/hint/search?q=markdownlint))
826
+ * [webpack](https://webpack.js.org/) ([Search repository](https://github.com/webpack/webpack.js.org/search?q=markdownlint))
827
+ * [WordPress](https://wordpress.org/gutenberg/) ([Search repository](https://github.com/WordPress/gutenberg/search?q=markdownlint))
828
+
829
+ ## Contributing
830
+
831
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for more information.
832
+
833
+ ## History
834
+
835
+ * 0.0.1 - Initial release, includes tests MD001-MD032.
836
+ * 0.0.2 - Improve documentation, tests, and code.
837
+ * 0.0.3 - Add synchronous API, improve documentation and code.
838
+ * 0.0.4 - Add tests MD033-MD040, update dependencies.
839
+ * 0.0.5 - Add `strings` option to enable file-less scenarios, add in-browser demo.
840
+ * 0.0.6 - Improve performance, simplify in-browser, update dependencies.
841
+ * 0.0.7 - Add MD041, improve MD003, ignore front matter, update dependencies.
842
+ * 0.0.8 - Support disabling/enabling rules inline, improve code fence, dependencies.
843
+ * 0.1.0 - Add aliases, exceptions for MD033, exclusions for MD013, dependencies.
844
+ * 0.1.1 - Fix bug handling HTML in tables, reference markdownlint-cli.
845
+ * 0.2.0 - Add MD042/MD043, enhance MD002/MD003/MD004/MD007/MD011/MD025/MD041, dependencies.
846
+ * 0.3.0 - More detailed error reporting with `resultVersion`, enhance MD010/MD012/MD036,
847
+ fixes for MD027/MD029/MD030, include JSON schema, dependencies.
848
+ * 0.3.1 - Fix regressions in MD032/MD038, update dependencies.
849
+ * 0.4.0 - Add MD044, enhance MD013/MD032/MD041/MD042/MD043, fix for MD038, dependencies.
850
+ * 0.4.1 - Fixes for MD038/front matter, improvements to MD044, update dependencies.
851
+ * 0.5.0 - Add shareable configuration, `noInlineConfig` option, README links, fix MD030,
852
+ improve MD009/MD041, update dependencies.
853
+ * 0.6.0 - `resultVersion` defaults to 1 (breaking change), ignore HTML comments, TOML
854
+ front matter, fixes for MD044, update dependencies.
855
+ * 0.6.1 - Update `markdown-it` versioning, exclude demo/test from publishing.
856
+ * 0.6.2 - Improve MD013/MD027/MD034/MD037/MD038/MD041/MD044, update dependencies.
857
+ * 0.6.3 - Improve highlighting for MD020.
858
+ * 0.6.4 - Improve MD029/MD042, update dependencies.
859
+ * 0.7.0 - `resultVersion` defaults to 2 (breaking change), add MD045, improve MD029,
860
+ remove trimLeft/trimRight, split rules, refactor, update dependencies.
861
+ * 0.8.0 - Add support for using and authoring custom rules, improve MD004/MD007/MD013,
862
+ add `engines` to `package.json`, refactor, update dependencies.
863
+ * 0.8.1 - Update item loop to be iterative, improve MD014, update dependencies.
864
+ * 0.9.0 - Remove support for end-of-life Node versions 0.10/0.12/4, change "header" to
865
+ "heading" per spec (non-breaking), improve MD003/MD009/MD041, handle uncommon
866
+ line-break characters, refactor for ES6, update dependencies.
867
+ * 0.10.0 - Add support for non-JSON configuration files, pass file/string name to custom
868
+ rules, update dependencies.
869
+ * 0.11.0 - Improve MD005/MD024/MD029/MD038, improve custom rule example, add CONTRIBUTING.md,
870
+ update dependencies.
871
+ * 0.12.0 - Add `information` link for custom rules, `markdownItPlugins` for extensibility,
872
+ improve MD023/MD032/MD038, update dependencies.
873
+ * 0.13.0 - Improve MD013/MD022/MD025/MD029/MD031/MD032/MD037/MD041/, deprecate MD002,
874
+ improve pandoc YAML support, update dependencies.
875
+ * 0.14.0 - Remove support for end-of-life Node version 6, introduce `markdownlint-rule-helpers`,
876
+ add MD046/MD047, improve MD033/MD034/MD039, improve custom rule validation and
877
+ in-browser demo, update dependencies.
878
+ * 0.14.1 - Improve MD033.
879
+ * 0.14.2 - Improve MD047, add `handleRuleFailures` option.
880
+ * 0.15.0 - Add `markdownlint-capture`/`markdownlint-restore` inline comments, improve
881
+ MD009/MD013/MD026/MD033/MD036, update dependencies.
882
+ * 0.16.0 - Add custom rule sample for linting code, improve MD026/MD031/MD033/MD038,
883
+ update dependencies.
884
+ * 0.17.0 - Add `resultVersion` 3 to support fix information for default and custom rules,
885
+ add fix information for 24 rules, update newline handling to match latest
886
+ CommonMark specification, improve MD014/MD037/MD039, update dependencies.
887
+ * 0.17.1 - Fix handling of front matter by fix information.
888
+ * 0.17.2 - Improve MD020/MD033/MD044.
889
+ * 0.18.0 - Add MD048/code-fence-style, add fix information for MD007/ul-indent, add
890
+ `markdownlint-disable-file`/`markdownlint-enable-file` inline comments, add
891
+ type declaration file (.d.ts) for TypeScript dependents, update schema, improve
892
+ MD006/MD007/MD009/MD013/MD030, update dependencies.
893
+ * 0.19.0 - Remove support for end-of-life Node version 8, add fix information for
894
+ MD005/list-indent, improve MD007/MD013/MD014, deprecate MD006/ul-start-left, add
895
+ rationale for every rule, update test runner and code coverage, add more JSDoc
896
+ comments, update dependencies.
897
+ * 0.20.0 - Add `markdownlint-configure-file` inline comment, reimplement MD037,
898
+ improve MD005/MD007/MD013/MD018/MD029/MD031/MD034/MD038/MD039, improve HTML
899
+ comment handling, update dependencies.
900
+ * 0.20.1 - Fix regression in MD037.
901
+ * 0.20.2 - Fix regression in MD037, improve MD038.
902
+ * 0.20.3 - Fix regression in MD037, improve MD044, add automatic regression testing.
903
+ * 0.20.4 - Fix regression in MD037, improve MD034/MD044, improve documentation.
904
+ * 0.21.0 - Lint concurrently for better performance (async only), add Promise-based APIs,
905
+ update TypeScript declaration file, hide `toString` on `LintResults`, add ability
906
+ to fix in browser demo, allow custom rules in `.markdownlint.json` schema, improve
907
+ MD042/MD044, improve documentation, update dependencies.
908
+ * 0.21.1 - Improve MD011/MD031, export `getVersion` API.
909
+
910
+ [npm-image]: https://img.shields.io/npm/v/markdownlint.svg
911
+ [npm-url]: https://www.npmjs.com/package/markdownlint
912
+ [ci-image]: https://github.com/DavidAnson/markdownlint/workflows/CI/badge.svg?branch=main
913
+ [ci-url]: https://github.com/DavidAnson/markdownlint/actions?query=branch%3Amain
914
+ [license-image]: https://img.shields.io/npm/l/markdownlint.svg
915
+ [license-url]: https://opensource.org/licenses/MIT