[GH-ISSUE #100] Mapped header names for specific header tags #1931

Open
opened 2026-03-07 20:02:52 +03:00 by kerem · 8 comments
Owner

Originally created by @ajithr on GitHub (Dec 26, 2017).
Original GitHub issue: https://github.com/DavidAnson/markdownlint/issues/100

It would be better, if it is possible to add the mapped headers for specific heading tags in a file. i.e. the required-headers can order the heading with specific header name, like wise the mapped headers can be useful to map a set of header names to specific heading tag.

Example:

"map044": {
        "headers": [
            "# Changelog",           
            "#### Bug Fixes",
            "#### New Features"
        ]
    }

So it will restrict the header tags with specified headings in the file contents. The unspecified header tags will be free from the restriction, in other words any heading name can be assigned to unspecified header tags.

Originally created by @ajithr on GitHub (Dec 26, 2017). Original GitHub issue: https://github.com/DavidAnson/markdownlint/issues/100 It would be better, if it is possible to add the mapped headers for specific heading tags in a file. i.e. the required-headers can order the heading with specific header name, like wise the mapped headers can be useful to map a set of header names to specific heading tag. **Example:** ``` "map044": { "headers": [ "# Changelog", "#### Bug Fixes", "#### New Features" ] } ``` So it will restrict the header tags with specified headings in the file contents. The unspecified header tags will be free from the restriction, in other words any heading name can be assigned to unspecified header tags.
Author
Owner

@ajithr commented on GitHub (Dec 26, 2017):

A simple implementation for the above requirement,

{
        "name": "map044",
        "desc": "Mapped heading names for header tags",
        "tags": ["headers"],
        "aliases": ["mapped-headers"],
        "regexp": null,
        "func": function map044(params, errors) {
            var requiredHeaders = params.options.headers;
            if (requiredHeaders) {
                var levels = {},
                    expected = {};
                [1, 2, 3, 4, 5, 6].forEach(function forLevel(level) {
                    levels["h" + level] = "######".substr(-level);
                    expected["h" + level] = requiredHeaders.filter(function(value, index) {
                        if (value.split(' ')[0] === levels["h" + level]) {
                            return value;
                        }
                    })
                });
                forEachHeading(params, function forHeading(heading, content) {
                    var tag = heading.tag;
                    var actual = levels[tag] + " " + content;
                    if (expected[tag].length && expected[tag].indexOf(actual) === -1) {
                        var errorDeail = '\nActual: ' + actual + '\nExpected: \n' + expected[tag].join('\n');
                        errors.addDetail(heading.lineNumber, errorDeail);
                    }
                });
            }
        }
    }

<!-- gh-comment-id:353961636 --> @ajithr commented on GitHub (Dec 26, 2017): A simple implementation for the above requirement, ``` { "name": "map044", "desc": "Mapped heading names for header tags", "tags": ["headers"], "aliases": ["mapped-headers"], "regexp": null, "func": function map044(params, errors) { var requiredHeaders = params.options.headers; if (requiredHeaders) { var levels = {}, expected = {}; [1, 2, 3, 4, 5, 6].forEach(function forLevel(level) { levels["h" + level] = "######".substr(-level); expected["h" + level] = requiredHeaders.filter(function(value, index) { if (value.split(' ')[0] === levels["h" + level]) { return value; } }) }); forEachHeading(params, function forHeading(heading, content) { var tag = heading.tag; var actual = levels[tag] + " " + content; if (expected[tag].length && expected[tag].indexOf(actual) === -1) { var errorDeail = '\nActual: ' + actual + '\nExpected: \n' + expected[tag].join('\n'); errors.addDetail(heading.lineNumber, errorDeail); } }); } } } ```
Author
Owner

@DavidAnson commented on GitHub (Dec 26, 2017):

The description and code above look very similar to existing rule MD043: https://github.com/DavidAnson/markdownlint/blob/master/doc/Rules.md#md043---required-header-structure

Could you please explain more about the scenario the proposed rule would improve and provide an example document?

My first thought is that this new rule is a subset of MD043 - an example would help clarify things.

Thank you!

<!-- gh-comment-id:353998646 --> @DavidAnson commented on GitHub (Dec 26, 2017): The description and code above look very similar to existing rule MD043: https://github.com/DavidAnson/markdownlint/blob/master/doc/Rules.md#md043---required-header-structure Could you please explain more about the scenario the proposed rule would improve and provide an example document? My first thought is that this new rule is a subset of MD043 - an example would help clarify things. Thank you!
Author
Owner

@ajithr commented on GitHub (Dec 27, 2017):

I have addressed the difference between required-headers and mapped-headers rules as below

required-headers mapped-headers
It restricts the header order with its heading name It will restrict the specific header tags with its heading name
It needs all header names with its order in a file It needs specific header tags with its name list
Example:
# Head
## Item
### Detail
## Foot
### Notes
Example:
# Changelog
### New Features
### Bug Fixes

From the above example, required-headers provides an ordered output for mdlint, whereas the mapped-headers will provide the support for specific header tag with its heading name.

  • mapped-headers won't need to be ordered like required-headers
  • mapped-headers only validates the heading names based on its header tag value. i.e. h1, h2
  • mapped-headers validates the provided list of header tag with its corresponding header names. i.e. it will not check other header tags. from the example, mapped-headers only validates the h1 and h3 tags with provided header names and it will not consider h2, h4, etc..

Note: The behavior of both rules are differ, so mapped-headers can be used as a separate rule. I don't know it is possible to achieve the above requirement with required-headers.

A simple testing behavior:

Input:

"headers": [
            "# Changelog",           
            "### Bug Fixes",
            "### New Features"
        ]

Output

Actual Expected Result
# Changelog # Changelog Success
# Component # Changelog Failure
## How to write? null N/A
### Bug Fixes ### Bug Fixes
### New Features
Success
### New features ### Bug Fixes
### New Features
Failure
#### Test Cases null N/A
<!-- gh-comment-id:354079360 --> @ajithr commented on GitHub (Dec 27, 2017): I have addressed the difference between `required-headers` and `mapped-headers` rules as below | required-headers | mapped-headers | |--------------------|---------------------| | It restricts the header order with its heading name | It will restrict the specific header tags with its heading name | | It needs all header names with its order in a file | It needs specific header tags with its name list | | **Example:**<br/># Head<br/>## Item<br/>### Detail<br/>## Foot<br/>### Notes | **Example:**<br/># Changelog<br/>### New Features<br/>### Bug Fixes | From the above example, `required-headers` provides an ordered output for mdlint, whereas the `mapped-headers` will provide the support for specific header tag with its heading name. - `mapped-headers` won't need to be ordered like `required-headers` - `mapped-headers` only validates the heading names based on its header tag value. i.e. h1, h2 - `mapped-headers` validates the provided list of header tag with its corresponding header names. i.e. it will not check other header tags. from the example, `mapped-headers` only validates the h1 and h3 tags with provided header names and it will not consider h2, h4, etc.. **Note:** The behavior of both rules are differ, so `mapped-headers` can be used as a separate rule. I don't know it is possible to achieve the above requirement with `required-headers`. A simple testing behavior: **Input:** ``` "headers": [ "# Changelog", "### Bug Fixes", "### New Features" ] ``` **Output** | Actual | Expected | Result | |--------|------------|--------| | # Changelog | # Changelog | Success | | # Component | # Changelog | Failure | | ## How to write? | null | N/A | | ### Bug Fixes | ### Bug Fixes<br/>### New Features | Success | | ### New features | ### Bug Fixes<br/>### New Features | Failure | | #### Test Cases | null | N/A |
Author
Owner

@DavidAnson commented on GitHub (Dec 27, 2017):

Got it - thank you for clarifying! required-headers allows you to skip using *, but I see that mapped-headers is solving a slightly different problem.

<!-- gh-comment-id:354172303 --> @DavidAnson commented on GitHub (Dec 27, 2017): Got it - thank you for clarifying! `required-headers` allows you to skip using `*`, but I see that `mapped-headers` is solving a slightly different problem.
Author
Owner

@ajithr commented on GitHub (Dec 28, 2017):

@DavidAnson Thanks for accepting this requirement as a new rule. May I know when it will be added in the markdownlint plugin. We need this requirement for md linting, so that only I have prepared a simple implementation mentioned above.

<!-- gh-comment-id:354220839 --> @ajithr commented on GitHub (Dec 28, 2017): @DavidAnson Thanks for accepting this requirement as a new rule. May I know when it will be added in the markdownlint plugin. We need this requirement for md linting, so that only I have prepared a simple implementation mentioned above.
Author
Owner

@DavidAnson commented on GitHub (Dec 28, 2017):

I do not have an estimate; I am working on a different set of changes for now. I am also looking at enabling user-defined rules, which would enable you to add this on your own. Thanks for your patience!

<!-- gh-comment-id:354232452 --> @DavidAnson commented on GitHub (Dec 28, 2017): I do not have an estimate; I am working on a different set of changes for now. I am also looking at enabling user-defined rules, which would enable you to add this on your own. Thanks for your patience!
Author
Owner

@ajithr commented on GitHub (Dec 28, 2017):

Thanks for the info. Can you please share the link for this enabling user-defined rules for tracking purpose. It will be helpful to me to add custom rules from my end.

<!-- gh-comment-id:354243158 --> @ajithr commented on GitHub (Dec 28, 2017): Thanks for the info. Can you please share the link for this enabling user-defined rules for tracking purpose. It will be helpful to me to add custom rules from my end.
Author
Owner

@DavidAnson commented on GitHub (Dec 28, 2017):

It is not implemented yet. Once I have something working, I plan to release a new version soon afterward.

<!-- gh-comment-id:354328343 --> @DavidAnson commented on GitHub (Dec 28, 2017): It is not implemented yet. Once I have something working, I plan to release a new version soon afterward.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/markdownlint#1931
No description provided.