markdownlint 0.41.1 → 0.42.0

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 (56) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/CONTRIBUTING.md +62 -77
  3. package/README.md +7 -7
  4. package/doc/CustomRules.md +6 -4
  5. package/doc/Rules.md +76 -35
  6. package/doc/md010.md +0 -1
  7. package/doc/md024.md +1 -1
  8. package/doc/md043.md +47 -9
  9. package/doc/md051.md +19 -19
  10. package/doc/md055.md +6 -3
  11. package/doc/md060.md +3 -2
  12. package/helpers/README.md +2 -2
  13. package/helpers/helpers.cjs +16 -7
  14. package/helpers/micromark-helpers.cjs +7 -10
  15. package/helpers/package.json +1 -5
  16. package/lib/configuration-strict.d.ts +124 -112
  17. package/lib/constants.mjs +1 -1
  18. package/lib/defer-require.cjs +1 -0
  19. package/lib/exports.d.mts +29 -1
  20. package/lib/markdownit.cjs +8 -1
  21. package/lib/markdownlint.d.mts +337 -195
  22. package/lib/markdownlint.mjs +78 -85
  23. package/lib/md007.mjs +2 -2
  24. package/lib/md009.mjs +2 -3
  25. package/lib/md010.mjs +1 -1
  26. package/lib/md011.mjs +10 -7
  27. package/lib/md012.mjs +1 -1
  28. package/lib/md013.mjs +13 -9
  29. package/lib/md018.mjs +1 -1
  30. package/lib/md020.mjs +1 -1
  31. package/lib/md022.mjs +5 -6
  32. package/lib/md025.mjs +1 -1
  33. package/lib/md027.mjs +1 -1
  34. package/lib/md028.mjs +1 -2
  35. package/lib/md029.mjs +1 -2
  36. package/lib/md030.mjs +4 -4
  37. package/lib/md031.mjs +1 -1
  38. package/lib/md033.mjs +1 -1
  39. package/lib/md034.mjs +1 -1
  40. package/lib/md039.mjs +5 -1
  41. package/lib/md041.mjs +1 -1
  42. package/lib/md043.mjs +98 -44
  43. package/lib/md044.mjs +2 -2
  44. package/lib/md048.mjs +1 -3
  45. package/lib/md051.mjs +2 -3
  46. package/lib/md055.mjs +11 -1
  47. package/lib/md056.mjs +1 -1
  48. package/lib/md058.mjs +1 -1
  49. package/lib/md060.mjs +24 -4
  50. package/lib/micromark-parse.mjs +1 -1
  51. package/lib/resolve-module.d.cts +15 -10
  52. package/package.json +31 -34
  53. package/schema/.markdownlint.jsonc +54 -54
  54. package/schema/.markdownlint.yaml +54 -54
  55. package/schema/markdownlint-config-schema-strict.json +126 -118
  56. package/schema/markdownlint-config-schema.json +126 -118
package/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.42.0
4
+
5
+ - Improve MD011/MD018/MD020/MD043/MD051/MD055/MD060
6
+ - Add regular expression denial of service protection
7
+ - Add support for reporting issues with front matter
8
+ - Update dependencies
9
+
3
10
  ## 0.41.1
4
11
 
5
12
  - Improve MD029
@@ -533,3 +540,14 @@
533
540
 
534
541
  - Initial release
535
542
  - Includes tests MD001-MD032
543
+
544
+ <!-- markdownlint-configure-file {
545
+ "required-headings": {
546
+ "headings": [
547
+ "# Changelog",
548
+ "^",
549
+ "%% ^\\d+\\.\\d+\\.\\d+$",
550
+ "^"
551
+ ]
552
+ }
553
+ } -->
package/CONTRIBUTING.md CHANGED
@@ -3,90 +3,75 @@
3
3
  Interested in contributing? Great! Here are some suggestions to make it a good
4
4
  experience:
5
5
 
6
- Start by [opening an issue](https://github.com/DavidAnson/markdownlint/issues),
7
- whether to identify a problem or outline a change. That issue should be used to
8
- discuss the situation and agree on a plan of action before writing code or
9
- sending a pull request. Maybe the problem isn't really a problem, or maybe there
10
- are more things to consider. If so, it's best to realize that before spending
11
- time and effort writing code that may not get used.
6
+ Start by [opening an issue][issues], whether to identify a problem or outline a
7
+ change. That issue should be used to discuss the situation and agree on a plan
8
+ of action before writing code or sending a pull request. Maybe the problem isn't
9
+ really a problem, or maybe there are more things to consider. If so, it's best
10
+ to realize that before spending time and effort writing code that gets rejected.
12
11
 
13
12
  Match the coding style of the files you edit. Although everyone has their own
14
13
  preferences and opinions, a pull request is not the right forum to debate them.
15
14
 
16
- Do not add new [`dependencies` to `package.json`][dependencies]. The Markdown
17
- parser [`micromark`][micromark] (and its extensions) is this project's only
18
- dependency.
15
+ Do not add new [`dependencies` to `package.json`][deps].
19
16
 
20
17
  Package versions for `dependencies` and `devDependencies` should be specified
21
- exactly (also known as "pinning"). The short explanation is that doing otherwise
22
- eventually leads to inconsistent behavior and broken functionality. (See [Why I
23
- pin dependency versions in Node.js packages][version-pinning] for a longer
24
- explanation.)
25
-
26
- If developing a new rule, start by creating a [custom rule][custom-rules] in its
27
- own project. Once written, published, and tested in real world scenarios, open
28
- an issue to consider adding it to this project. For rule ideas, see [issues
29
- tagged with the `new rule` label][new-rule].
30
-
31
- Add tests for all new/changed functionality. Test positive and negative
32
- scenarios. Try to break the new code now, or else it will get broken later.
33
-
34
- Run tests before sending a pull request via `npm test` in the [usual
35
- manner][npm-scripts]. Tests should all pass on all platforms. The test runner is
36
- [AVA][ava] and test cases are located in `test/markdownlint-test*.js`. When
37
- running tests, `test/*.md` files are enumerated, linted, and fail if any
38
- violations are missing a corresponding `{MD###}` marker in the test file. For
39
- example, the line `### Heading {MD001}` is expected to trigger the rule `MD001`.
40
- For cases where the marker text can not be present on the same line, the syntax
41
- `{MD###:#}` can be used to include a line number. If `some-test.md` needs custom
42
- configuration, a `some-test.json` is used to provide a custom `options.config`
43
- for that scenario. Tests run by `markdownlint-test-scenarios.js` use [AVA's
44
- snapshot feature][ava-snapshots]. To update snapshots (for example, after
45
- modifying a test file), run `npm run update-snapshots` and include the updated
46
- files with the pull request.
47
-
48
- Lint before sending a pull request by running `npm run lint`. There should be no
49
- issues.
50
-
51
- Run a full continuous integration pass before sending a pull request via `npm
52
- run ci`. Code coverage should always be 100%. As part of a continuous
53
- integration run, generated files may get updated and fail the run - commit them
54
- to the repository and rerun continuous integration.
55
-
56
- Pull requests should contain a single commit. If necessary, squash multiple
57
- commits before creating the pull request and when making changes. (See [Git
58
- Tools - Rewriting History][rewriting-history] for details.)
59
-
60
- Open pull requests against the `next` branch. That's where the latest changes
61
- are staged for the next release. Include the text "(fixes #??)" at the end of
18
+ exactly (also known as "pinning"). Doing otherwise causes inconsistent behavior
19
+ and broken functionality. (See [Why I pin dependency versions in Node.js
20
+ packages][pinning] for a longer explanation.)
21
+
22
+ Add tests for all new/changed functionality. Test both positive and negative
23
+ scenarios. Try to break the new code now, or it will get broken later. This
24
+ project maintains 100% code coverage.
25
+
26
+ Run tests before sending a pull request via `npm test`. Tests need to pass on
27
+ all platforms. Test cases are implemented in `test/*.mjs`. As part of testing,
28
+ `test/*.md` files are enumerated, linted, and fail if any violations are missing
29
+ a corresponding `{MD###}` marker in the test file. For cases where a marker can
30
+ not be present on the corresponding line, the syntax `{MD###:#}`can be used. To
31
+ update test snapshots (for example, after modifying a test file), use `npm run
32
+ update-snapshots` and include the updated snapshot files with the pull request.
33
+
34
+ Run a full continuous integration pass before opening a pull request via `npm
35
+ run ci`. As part of the continuous integration run, generated files may get
36
+ updated and fail the run - commit those changes and rerun.
37
+
38
+ Pull requests should contain a single commit with a commit message that is a
39
+ brief sentence with punctuation. Include the text "(fixes #??)" at the end of
62
40
  the commit message so the pull request will be associated with the relevant
63
- issue. End commit messages with a period (`.`). Once accepted, the tag `fixed in
64
- next` will be added to the issue. When the commit is merged to the main branch
65
- during the release process, the issue will be closed automatically. (See
66
- [Closing issues using keywords][closing-keywords] for details.)
67
-
68
- Please refrain from using slang or meaningless placeholder words. Sample content
69
- can be "text", "code", "heading", or the like. Sample URLs should use
70
- [example.com][example-com] which is safe for this purpose. Profanity is not
71
- allowed.
72
-
73
- In order to maintain the permissive MIT license this project uses, all
74
- contributions must be your own and released under that license. Code you add
75
- should be an original work and should not be copied from elsewhere. Taking code
76
- from a different project, Stack Overflow, or the like is not allowed. The use of
77
- tools such as GitHub Copilot, ChatGPT, LLMs (large language models), etc. that
78
- incorporate code from other projects is not allowed.
41
+ issue. Squash multiple commits before creating the pull request or when making
42
+ updates. (See [Git Tools - Rewriting History][rewriting] for details.)
43
+
44
+ Create all pull requests for the `next` branch which contains the latest changes
45
+ ready for release. Once accepted, the tag `fixed in next` will be added to the
46
+ issue. When that commit is merged to the `main` branch during the release
47
+ process, the issue will be closed automatically.
48
+
49
+ Refrain from using slang or meaningless placeholder text in code, documentation,
50
+ or tests. Sample content can be "text", "code", "heading", etc.. URLs should use
51
+ [example.com][example]. Profanity is not allowed.
52
+
53
+ When considering a new rule, start by creating a [custom rule][custom] in a
54
+ dedicated repository. Once it has been written, published, and tested in real-
55
+ world scenarios, open an issue to discuss adding it to this project. For rule
56
+ ideas, see [issues tagged with the `new rule` label][new]. Not all rules make
57
+ sense to include.
58
+
59
+ In order to maintain the permissive [MIT license][mit] this project has, all
60
+ contributions must be your own and released under the MIT license. Code you add
61
+ should be an original work and should not be copied from elsewhere. Reusing code
62
+ from a different project, Stack Overflow, etc. is not allowed. The use of tools
63
+ such as Copilot, ChatGPT, Claude, etc. that produce output from a [large
64
+ language model (LLM)][llm] is not allowed because LLMs reuse code from other
65
+ projects.
79
66
 
80
67
  Thank you!
81
68
 
82
- [ava]: https://github.com/avajs/ava
83
- [ava-snapshots]: https://github.com/avajs/ava/blob/main/docs/04-snapshot-testing.md
84
- [closing-keywords]: https://help.github.com/articles/closing-issues-using-keywords/
85
- [custom-rules]: doc/CustomRules.md
86
- [dependencies]: https://docs.npmjs.com/cli/v11/configuring-npm/package-json#dependencies
87
- [example-com]: https://wikipedia.org/wiki/Example.com
88
- [micromark]: https://www.npmjs.com/package/micromark
89
- [new-rule]: https://github.com/DavidAnson/markdownlint/labels/new%20rule
90
- [npm-scripts]: https://docs.npmjs.com/misc/scripts
91
- [rewriting-history]: https://git-scm.com/book/en/v2/Git-Tools-Rewriting-History
92
- [version-pinning]: https://dlaa.me/blog/post/versionpinning
69
+ [custom]: doc/CustomRules.md
70
+ [deps]: https://docs.npmjs.com/cli/v11/configuring-npm/package-json#dependencies
71
+ [example]: https://wikipedia.org/wiki/Example.com
72
+ [issues]: https://github.com/DavidAnson/markdownlint/issues
73
+ [llm]: https://wikipedia.org/wiki/Large_language_model
74
+ [mit]: https://choosealicense.com/licenses/mit/
75
+ [new]: https://github.com/DavidAnson/markdownlint/labels/new%20rule
76
+ [rewriting]: https://git-scm.com/book/en/v2/Git-Tools-Rewriting-History
77
+ [pinning]: https://dlaa.me/blog/post/versionpinning
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # markdownlint
2
2
 
3
- > A Node.js style checker and lint tool for Markdown/CommonMark files.
3
+ > A Node.js style checker and lint tool for Markdown/CommonMark files
4
4
 
5
5
  [![npm version][npm-image]][npm-url]
6
6
  [![License][license-image]][license-url]
@@ -574,7 +574,7 @@ ones.
574
574
  For example:
575
575
 
576
576
  ```javascript
577
- [ JSON.parse, require("toml").parse, require("js-yaml").load ]
577
+ [ JSON.parse, require("smol-toml").parse, require("js-yaml").load ]
578
578
  ```
579
579
 
580
580
  ##### options.customRules
@@ -830,7 +830,7 @@ parsers should come before flexible parsers.
830
830
  For example:
831
831
 
832
832
  ```javascript
833
- [ JSON.parse, require("toml").parse, require("js-yaml").load ]
833
+ [ JSON.parse, require("smol-toml").parse, require("js-yaml").load ]
834
834
  ```
835
835
 
836
836
  #### fs
@@ -970,7 +970,7 @@ All of which return an object like:
970
970
  { "lineNumber": 3,
971
971
  "ruleNames": [ "MD010", "no-hard-tabs" ],
972
972
  "ruleDescription": "Hard tabs",
973
- "ruleInformation": "https://github.com/DavidAnson/markdownlint/blob/v0.41.1/doc/md010.md",
973
+ "ruleInformation": "https://github.com/DavidAnson/markdownlint/blob/v0.42.0/doc/md010.md",
974
974
  "errorDetail": "Column: 17",
975
975
  "errorContext": null,
976
976
  "errorRange": [ 17, 1 ],
@@ -979,7 +979,7 @@ All of which return an object like:
979
979
  { "lineNumber": 1,
980
980
  "ruleNames": [ "MD018", "no-missing-space-atx" ],
981
981
  "ruleDescription": "No space after hash on atx style heading",
982
- "ruleInformation": "https://github.com/DavidAnson/markdownlint/blob/v0.41.1/doc/md018.md",
982
+ "ruleInformation": "https://github.com/DavidAnson/markdownlint/blob/v0.42.0/doc/md018.md",
983
983
  "errorDetail": null,
984
984
  "errorContext": "#bad.md",
985
985
  "errorRange": [ 1, 2 ],
@@ -988,7 +988,7 @@ All of which return an object like:
988
988
  { "lineNumber": 3,
989
989
  "ruleNames": [ "MD018", "no-missing-space-atx" ],
990
990
  "ruleDescription": "No space after hash on atx style heading",
991
- "ruleInformation": "https://github.com/DavidAnson/markdownlint/blob/v0.41.1/doc/md018.md",
991
+ "ruleInformation": "https://github.com/DavidAnson/markdownlint/blob/v0.42.0/doc/md018.md",
992
992
  "errorDetail": null,
993
993
  "errorContext": "#This file fails\tsome rules.",
994
994
  "errorRange": [ 1, 2 ],
@@ -997,7 +997,7 @@ All of which return an object like:
997
997
  { "lineNumber": 1,
998
998
  "ruleNames": [ "MD041", "first-line-heading", "first-line-h1" ],
999
999
  "ruleDescription": "First line in a file should be a top-level heading",
1000
- "ruleInformation": "https://github.com/DavidAnson/markdownlint/blob/v0.41.1/doc/md041.md",
1000
+ "ruleInformation": "https://github.com/DavidAnson/markdownlint/blob/v0.42.0/doc/md041.md",
1001
1001
  "errorDetail": null,
1002
1002
  "errorContext": "#bad.md",
1003
1003
  "errorRange": null,
@@ -117,12 +117,14 @@ A rule is implemented as an `Object`:
117
117
  - `lines` is an `Array` of `String` values corresponding to the lines of the
118
118
  input file/string.
119
119
  - `frontMatterLines` is an `Array` of `String` values corresponding to any
120
- front matter (not present in `lines`).
120
+ lines of front matter (not present in the `lines` `Array`).
121
121
  - `config` is an `Object` corresponding to the rule's entry in
122
122
  `options.config` (if present).
123
123
  - `version` is a `String` that corresponds to the version of `markdownlint`
124
124
  - `onError` is a function that takes a single `Object` parameter with one
125
- required and four optional properties:
125
+ required and various optional properties:
126
+ - `frontMatter` is an optional `Boolean` value specifying whether the error
127
+ refers to `frontMatterLines` (instead of `lines` which is the default)
126
128
  - `lineNumber` is a required `Number` specifying the 1-based line number of
127
129
  the error.
128
130
  - `detail` is an optional `String` with information about what caused the
@@ -147,8 +149,8 @@ A rule is implemented as an `Object`:
147
149
  is the platform-independent way to add a line break; line breaks should
148
150
  be added at the beginning of a line instead of at the end.
149
151
 
150
- The collection of helper functions shared by the built-in rules is available for
151
- use by custom rules in the [markdownlint-rule-helpers package][rule-helpers].
152
+ A collection of helper functions (formerly) used by built-in rules is available
153
+ for custom rules in the [markdownlint-rule-helpers package][rule-helpers].
152
154
 
153
155
  ### Asynchronous Rules
154
156
 
package/doc/Rules.md CHANGED
@@ -400,7 +400,6 @@ More information:
400
400
 
401
401
  - <https://agiletribe.wordpress.com/2011/10/27/18-dont-use-tab-characters/>
402
402
  - <https://www.jwz.org/doc/tabs-vs-spaces.html>
403
- - <https://adamspiers.org/computing/why_no_tabs.html>
404
403
 
405
404
  <a name="md011"></a>
406
405
 
@@ -860,7 +859,7 @@ If the parameter `siblings_only` is set to `true`, duplication is allowed for
860
859
  headings with different parents (as is common in changelogs):
861
860
 
862
861
  ```markdown
863
- # Change log
862
+ # Changelog
864
863
 
865
864
  ## 1.0.0
866
865
 
@@ -1841,7 +1840,7 @@ Aliases: `required-headings`
1841
1840
 
1842
1841
  Parameters:
1843
1842
 
1844
- - `headings`: List of headings (`string[]`, default `[]`)
1843
+ - `headings`: List of headings (`string[]|null`, default `null`)
1845
1844
  - `match_case`: Match case of headings (`boolean`, default `false`)
1846
1845
 
1847
1846
  This rule is triggered when the headings in a file do not match the array of
@@ -1872,13 +1871,15 @@ To allow optional headings as with the following structure:
1872
1871
  # Heading
1873
1872
  ## Item
1874
1873
  ### Detail (optional)
1874
+ ### Example (optional)
1875
1875
  ## Foot
1876
1876
  ### Notes (optional)
1877
1877
  ```
1878
1878
 
1879
- Use the special value `"*"` meaning "zero or more unspecified headings" or the
1880
- special value `"+"` meaning "one or more unspecified headings" and set the
1881
- `headings` parameter to:
1879
+ Use the special value `*` meaning "zero or more unspecified headings", the
1880
+ special value `+` meaning "one or more unspecified headings", or the special
1881
+ value `?` meaning "exactly one unspecified heading" and set the `headings`
1882
+ parameter to something like:
1882
1883
 
1883
1884
  ```json
1884
1885
  [
@@ -1886,28 +1887,64 @@ special value `"+"` meaning "one or more unspecified headings" and set the
1886
1887
  "## Item",
1887
1888
  "*",
1888
1889
  "## Foot",
1889
- "*"
1890
+ "+"
1890
1891
  ]
1891
1892
  ```
1892
1893
 
1893
- To allow a single required heading to vary as with a project name:
1894
+ To require a heading with a specific level and text matching a specific pattern
1895
+ (for example, a one-word project name):
1894
1896
 
1895
1897
  ```markdown
1896
- # Project Name
1898
+ # Project
1897
1899
  ## Description
1898
1900
  ## Examples
1899
1901
  ```
1900
1902
 
1901
- Use the special value `"?"` meaning "exactly one unspecified heading":
1903
+ Replace the `#` prefix character(s) with `%` and specify a regular expression;
1904
+ the following example requires a level 1 heading with a single word made up of
1905
+ at least 4 letters:
1902
1906
 
1903
1907
  ```json
1904
1908
  [
1905
- "?",
1909
+ "% [a-zA-Z]{4,}",
1906
1910
  "## Description",
1907
1911
  "## Examples"
1908
1912
  ]
1909
1913
  ```
1910
1914
 
1915
+ To handle repeating heading sections (common in `CHANGELOG` files) such as the
1916
+ following:
1917
+
1918
+ ```markdown
1919
+ # Changelog
1920
+ ## 1.0.0
1921
+ ### Fixes
1922
+ ### Features
1923
+ ## 2.0.0
1924
+ ### Fixes
1925
+ ### Features
1926
+ ```
1927
+
1928
+ Use the special value `^` meaning "if the next heading does not match, loop
1929
+ back to the previous matching marker":
1930
+
1931
+ ```json
1932
+ [
1933
+ "# Changelog",
1934
+ "^",
1935
+ "%% ^\\d+\\.\\d+\\.\\d+$",
1936
+ "### Fixes",
1937
+ "### Features",
1938
+ "^"
1939
+ ]
1940
+ ```
1941
+
1942
+ The simple form shown above is enough for most scenarios; if multiple loops are
1943
+ needed, matching pairs of `^^`, `^^^`, etc. can be used in conjunction. The
1944
+ prefix `%` and the special value `?` are supported with loops, but `*` and `+`
1945
+ are not and will result in undefined behavior. To avoid infinite looping, a
1946
+ violation is reported if the rule loops more than 1,000 times.
1947
+
1911
1948
  When an error is detected, this rule outputs the line number of the first
1912
1949
  problematic heading (otherwise, it outputs the last line number of the file).
1913
1950
 
@@ -2239,7 +2276,7 @@ Parameters:
2239
2276
  Fixable: Some violations can be fixed by tooling
2240
2277
 
2241
2278
  This rule is triggered when a link fragment does not match any of the fragments
2242
- that are automatically generated for headings in a document:
2279
+ that are automatically generated by GitHub for headings in the document:
2243
2280
 
2244
2281
  ```markdown
2245
2282
  # Heading Name
@@ -2257,8 +2294,9 @@ generated name (see below):
2257
2294
  ```
2258
2295
 
2259
2296
  For consistency, this rule requires fragments to exactly match the [GitHub
2260
- heading algorithm][github-heading-algorithm] which converts letters to
2261
- lowercase. Therefore, the following example is reported as a violation:
2297
+ algorithm for section links][github-section-links] which (among other things)
2298
+ converts letters to lowercase. Therefore, the following is reported as a
2299
+ violation:
2262
2300
 
2263
2301
  ```markdown
2264
2302
  # Heading Name
@@ -2270,9 +2308,9 @@ To ignore case when comparing fragments with heading names, the `ignore_case`
2270
2308
  parameter can be set to `true`. In this configuration, the previous example is
2271
2309
  not reported as a violation.
2272
2310
 
2273
- Alternatively, some platforms allow the syntax `{#named-anchor}` to be used
2274
- within a heading to provide a specific name (consisting of only lower-case
2275
- letters, numbers, `-`, and `_`):
2311
+ Some platforms allow the syntax `{#named-anchor}` to be used within a heading to
2312
+ provide a specific name (consisting of only lower-case letters, numbers, `-`,
2313
+ and `_`); that is allowed by this rule:
2276
2314
 
2277
2315
  ```markdown
2278
2316
  # Heading Name {#custom-name}
@@ -2289,8 +2327,8 @@ attribute can be used to define a fragment:
2289
2327
  [Link](#bookmark)
2290
2328
  ```
2291
2329
 
2292
- An `a` tag can be useful in scenarios where a heading is not appropriate or for
2293
- control over the text of the fragment identifier.
2330
+ Using an `a` tag can be useful in scenarios where a heading is not appropriate
2331
+ or for control over the text of the fragment identifier.
2294
2332
 
2295
2333
  [HTML links to `#top` scroll to the top of a document][html-top-fragment]. This
2296
2334
  rule allows that syntax (using lower-case for consistency):
@@ -2299,16 +2337,15 @@ rule allows that syntax (using lower-case for consistency):
2299
2337
  [Link](#top)
2300
2338
  ```
2301
2339
 
2302
- This rule also recognizes the custom fragment syntax used by GitHub to highlight
2303
- [specific content in a document][github-linking-to-content].
2304
-
2305
- For example, this link to line 20:
2340
+ This rule supports the fragment syntax used by GitHub to highlight [specific
2341
+ lines/sections of a document][github-linking-to-content]. For example, this link
2342
+ to line 20:
2306
2343
 
2307
2344
  ```markdown
2308
2345
  [Link](#L20)
2309
2346
  ```
2310
2347
 
2311
- And this link to content starting within line 19 running into line 21:
2348
+ And this link to content starting within line 19 running partly through line 21:
2312
2349
 
2313
2350
  ```markdown
2314
2351
  [Link](#L19C5-L21C11)
@@ -2317,8 +2354,8 @@ And this link to content starting within line 19 running into line 21:
2317
2354
  Some Markdown generators dynamically create and insert headings when building
2318
2355
  documents, for example by combining a fixed prefix like `figure-` and an
2319
2356
  incrementing numeric counter. To ignore such generated fragments, set the
2320
- `ignored_pattern` [regular expression][RegEx] parameter to a pattern that
2321
- matches (e.g., `^figure-`).
2357
+ `ignored_pattern` [regular expression][RegEx] parameter to a suitable pattern
2358
+ (e.g., `^figure-`).
2322
2359
 
2323
2360
  Rationale: [GitHub section links][github-section-links] are created
2324
2361
  automatically for every heading when Markdown content is displayed on GitHub.
@@ -2327,17 +2364,17 @@ However, section links change if headings are renamed or removed. This rule
2327
2364
  helps identify broken section links within a document.
2328
2365
 
2329
2366
  Note: Section links are **not** part of the CommonMark specification; this rule
2330
- enforces the [GitHub heading algorithm][github-heading-algorithm]:
2367
+ enforces the GitHub algorithm. Basically:
2331
2368
 
2332
2369
  1. Convert text to lowercase
2333
2370
  2. Remove punctuation characters
2334
2371
  3. Convert spaces to dashes
2335
- 4. Append an incrementing integer (as needed for uniqueness)
2336
- 5. [URI-encode][encodeURIComponent] the result
2372
+ 4. Remove HTML comments
2373
+ 5. Append dash+incrementing integer if needed for uniqueness
2374
+ 6. [URI-encode][encodeURIComponent] the result
2337
2375
 
2338
2376
  [encodeURIComponent]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent
2339
2377
  [github-section-links]: https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax#section-links
2340
- [github-heading-algorithm]: https://github.com/gjtorikian/html-pipeline/blob/f13a1534cb650ba17af400d1acd3a22c28004c09/lib/html/pipeline/toc_filter.rb
2341
2378
  [github-linking-to-content]: https://docs.github.com/en/get-started/writing-on-github/working-with-advanced-formatting/creating-a-permanent-link-to-a-code-snippet#linking-to-markdown
2342
2379
  [html-top-fragment]: https://html.spec.whatwg.org/multipage/browsing-the-web.html#scrolling-to-a-fragment
2343
2380
  [RegEx]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_expressions
@@ -2553,15 +2590,18 @@ Parameters:
2553
2590
 
2554
2591
  - `style`: Table pipe style (`string`, default `consistent`, values
2555
2592
  `consistent` / `leading_and_trailing` / `leading_only` /
2556
- `no_leading_or_trailing` / `trailing_only`)
2593
+ `no_leading_or_trailing` / `per_table` / `trailing_only`)
2557
2594
 
2558
2595
  This rule is triggered when a [GitHub Flavored Markdown table][gfm-table-055]
2559
- is inconsistent about its use of leading and trailing pipe characters (`|`).
2596
+ is inconsistent with its use of leading and trailing pipe characters (`|`).
2560
2597
 
2561
2598
  By default (`consistent` style), the header row of the first table in a document
2562
2599
  is used to determine the style that is enforced for every table in the document.
2563
2600
  A specific style can be used instead (`leading_and_trailing`, `leading_only`,
2564
- `no_leading_or_trailing`, `trailing_only`).
2601
+ `no_leading_or_trailing`, `trailing_only`) to require all tables in a document
2602
+ have the same approach. The style `per_table` can be used to require the rows of
2603
+ each table use the same approach (based on its header row) while allowing tables
2604
+ in a document to differ from each other.
2565
2605
 
2566
2606
  This table's header row has leading and trailing pipes, but its delimiter row is
2567
2607
  missing the trailing pipe and its first row of cells is missing the leading
@@ -2765,7 +2805,8 @@ The `aligned` style ignores cell content, so the following is also valid:
2765
2805
  | N | No |
2766
2806
  ```
2767
2807
 
2768
- Style `compact` avoids extra padding with a single space around cell content:
2808
+ Style `compact` avoids extra padding with a single space before and after cell
2809
+ content (or just a single space for cells without content):
2769
2810
 
2770
2811
  ```markdown
2771
2812
  | Character | Meaning |
@@ -2774,7 +2815,7 @@ Style `compact` avoids extra padding with a single space around cell content:
2774
2815
  | N | No |
2775
2816
  ```
2776
2817
 
2777
- Style `tight` uses no padding at all for cell content:
2818
+ Style `tight` uses no padding at all (for cells with or without content):
2778
2819
 
2779
2820
  ```markdown
2780
2821
  |Character|Meaning|
package/doc/md010.md CHANGED
@@ -59,4 +59,3 @@ More information:
59
59
 
60
60
  - <https://agiletribe.wordpress.com/2011/10/27/18-dont-use-tab-characters/>
61
61
  - <https://www.jwz.org/doc/tabs-vs-spaces.html>
62
- - <https://adamspiers.org/computing/why_no_tabs.html>
package/doc/md024.md CHANGED
@@ -29,7 +29,7 @@ If the parameter `siblings_only` is set to `true`, duplication is allowed for
29
29
  headings with different parents (as is common in changelogs):
30
30
 
31
31
  ```markdown
32
- # Change log
32
+ # Changelog
33
33
 
34
34
  ## 1.0.0
35
35
 
package/doc/md043.md CHANGED
@@ -6,7 +6,7 @@ Aliases: `required-headings`
6
6
 
7
7
  Parameters:
8
8
 
9
- - `headings`: List of headings (`string[]`, default `[]`)
9
+ - `headings`: List of headings (`string[]|null`, default `null`)
10
10
  - `match_case`: Match case of headings (`boolean`, default `false`)
11
11
 
12
12
  This rule is triggered when the headings in a file do not match the array of
@@ -37,13 +37,15 @@ To allow optional headings as with the following structure:
37
37
  # Heading
38
38
  ## Item
39
39
  ### Detail (optional)
40
+ ### Example (optional)
40
41
  ## Foot
41
42
  ### Notes (optional)
42
43
  ```
43
44
 
44
- Use the special value `"*"` meaning "zero or more unspecified headings" or the
45
- special value `"+"` meaning "one or more unspecified headings" and set the
46
- `headings` parameter to:
45
+ Use the special value `*` meaning "zero or more unspecified headings", the
46
+ special value `+` meaning "one or more unspecified headings", or the special
47
+ value `?` meaning "exactly one unspecified heading" and set the `headings`
48
+ parameter to something like:
47
49
 
48
50
  ```json
49
51
  [
@@ -51,28 +53,64 @@ special value `"+"` meaning "one or more unspecified headings" and set the
51
53
  "## Item",
52
54
  "*",
53
55
  "## Foot",
54
- "*"
56
+ "+"
55
57
  ]
56
58
  ```
57
59
 
58
- To allow a single required heading to vary as with a project name:
60
+ To require a heading with a specific level and text matching a specific pattern
61
+ (for example, a one-word project name):
59
62
 
60
63
  ```markdown
61
- # Project Name
64
+ # Project
62
65
  ## Description
63
66
  ## Examples
64
67
  ```
65
68
 
66
- Use the special value `"?"` meaning "exactly one unspecified heading":
69
+ Replace the `#` prefix character(s) with `%` and specify a regular expression;
70
+ the following example requires a level 1 heading with a single word made up of
71
+ at least 4 letters:
67
72
 
68
73
  ```json
69
74
  [
70
- "?",
75
+ "% [a-zA-Z]{4,}",
71
76
  "## Description",
72
77
  "## Examples"
73
78
  ]
74
79
  ```
75
80
 
81
+ To handle repeating heading sections (common in `CHANGELOG` files) such as the
82
+ following:
83
+
84
+ ```markdown
85
+ # Changelog
86
+ ## 1.0.0
87
+ ### Fixes
88
+ ### Features
89
+ ## 2.0.0
90
+ ### Fixes
91
+ ### Features
92
+ ```
93
+
94
+ Use the special value `^` meaning "if the next heading does not match, loop
95
+ back to the previous matching marker":
96
+
97
+ ```json
98
+ [
99
+ "# Changelog",
100
+ "^",
101
+ "%% ^\\d+\\.\\d+\\.\\d+$",
102
+ "### Fixes",
103
+ "### Features",
104
+ "^"
105
+ ]
106
+ ```
107
+
108
+ The simple form shown above is enough for most scenarios; if multiple loops are
109
+ needed, matching pairs of `^^`, `^^^`, etc. can be used in conjunction. The
110
+ prefix `%` and the special value `?` are supported with loops, but `*` and `+`
111
+ are not and will result in undefined behavior. To avoid infinite looping, a
112
+ violation is reported if the rule loops more than 1,000 times.
113
+
76
114
  When an error is detected, this rule outputs the line number of the first
77
115
  problematic heading (otherwise, it outputs the last line number of the file).
78
116