markdownlint icon indicating copy to clipboard operation
markdownlint copied to clipboard

Mapped header names for specific header tags

Open ajithr opened this issue 7 years ago • 8 comments

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.

ajithr avatar Dec 26 '17 12:12 ajithr

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);
                    }
                });
            }
        }
    }

ajithr avatar Dec 26 '17 12:12 ajithr

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!

DavidAnson avatar Dec 26 '17 18:12 DavidAnson

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

ajithr avatar Dec 27 '17 08:12 ajithr

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.

DavidAnson avatar Dec 27 '17 20:12 DavidAnson

@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.

ajithr avatar Dec 28 '17 03:12 ajithr

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!

DavidAnson avatar Dec 28 '17 05:12 DavidAnson

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.

ajithr avatar Dec 28 '17 07:12 ajithr

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

DavidAnson avatar Dec 28 '17 17:12 DavidAnson