GithubHelp home page GithubHelp logo

Comments (12)

DavidAnson avatar DavidAnson commented on August 19, 2024 1

Seems reasonable, I like the design you've proposed. I'll look into this soon when I work through the backlog of markdownlint issues. Thanks!

from markdownlint.

DavidAnson avatar DavidAnson commented on August 19, 2024 1

I went back and forth on this implementation a bunch. :| What ended up seeming like a reasonable first attempt is what you see in the associated commit. I think that it addresses the common scenarios clearly and in a way a beginner could use (using your syntax, with some changes). I will add more detailed custom error information as part of #23. I may still add RegExp support. If you feel this is not sufficient to start with, please let me know!

from markdownlint.

originalfoo avatar originalfoo commented on August 19, 2024

Example rule config:

{ headings: [ '# Introduction', '## About', '## Dependencies' ...], ordered: true }

The # at start of strings denotes heading level - if present, the rule also validates that the heading, if found, is using the specified heading level.

from markdownlint.

originalfoo avatar originalfoo commented on August 19, 2024

Here's a rough code draft if it's any use:

  {
    "name": "MD042",
    "desc": "Mandatory headers are missing or wrong level/sequence",
    "tags": [ "headers" ],
    "aliases": [ "mandatory-headings" ],
    "func": function MD042(params, errors) {
      /**
       * Example options:
       *
       * { headings: [ '# Overview', '## About', '## Notes' ], ordered: true }
       *
       * Notes:
       *  * No `#` for heading means "any level"
       *  * Rule ignores any headings not listed in array
       */
      if ( !params.options
        || !params.options.headings
        || !params.options.headings instanceof Array ) {
        return;
      }
      var headings = params.options.headings,
          ordered  = params.options.ordered || true;
      // Split headings array in to texts and levels arrays:
      var texts  = []; // heaidng text
      var levels = []; // heading level (0 if not specified)
      headings.forEach(function(heading, idx) {
        var hed = heading.split('#');
        texts[idx]  = hed.pop().trim(); // heading text
        levels[idx] = hed.length; // heading level
      });
      // Verify headings in target document:
      // If heading is found, it gets removed from texts/levels
      // array regardless of whether it has error
      forEachHeading(params, function forHeading(heading, content) {
        // heading = "heading_open" token
        var level = parseInt(heading.tag.slice(1), 10);
        // content = heading text
        var text  = content.trim();
        if (ordered) {
          if (texts[0] === text) { // found in right place
            if (levels[0] && levels[0] !== level)
              errors.push(heading.lineNumber);
            // remove form lists
            texts.shift();
            levels.shift();
          } else { // maybe it's out of sequence?
            var wrongPos = texts.indexOf(text);
            if (wrongPos > -1) { // found, but out of sequence
              errors.push(heading.lineNumber);
              // remove from lists
              texts.splice(wrongPos,1);
              levels.splice(wrongPos,1);
            }
          } // else ignore non-listed headings
        } else { // unordered
          var pos = texts.indexOf(text);
          if (pos > -1) { // found, order not important
            if (levels[pos] && levels[pos] !== level)
              errors.push(heading.lineNumber);
            // remove from lists
            texts.splice(pos,1);
            levels.splice(pos,1);
          } // else ignore non-listed headings
        }
      });
      // any missed headings?
      if (texts.length) errors.push(0);
    }
  },

from markdownlint.

DavidAnson avatar DavidAnson commented on August 19, 2024

Nice, thanks! I will think about the algorithm independently as well. Also, what about another option only=true to fail the check if some other header is present?

from markdownlint.

originalfoo avatar originalfoo commented on August 19, 2024

Yes, good idea!

from markdownlint.

DavidAnson avatar DavidAnson commented on August 19, 2024

Thinking about this in the context of something like Wikipedia, I'm not sure what we have so far is expressive enough. So I am playing with the idea of casting this as a regular expression scenario. Imagine if the list of headers was presented as a string similar to how you propose and then the rule runs a regular expression against it.

Example: # Intro\n# Body\n# Summary\n

This makes it possible to enforce simple rules like "exactly these three headers in this order", more complicated ones like "this set of 10 headers, 5 of which are optional", more generic ones like "only level one and two headings", or even stuff like "API documentation where each method is a level two heading followed by any number of level three headings for each parameter".

The concern I have with this is that violations will be harder to identify because there won't be meaningful line numbers. However, in order to cover the kinds of scenarios I see this being used for (GitHub Readme, OSS documentation), I'm thinking such a level of expressivity is necessary - and would be difficult to implement manually.

from markdownlint.

originalfoo avatar originalfoo commented on August 19, 2024

I agree the regex approach would be a big improvement in terms of flexibility, so long as your docs provide decent examples for scenarios you cited - regex are often difficult to comprehend for people involved in maintaining documentation and style guides, etc.

Maybe a helper function could be provided that would take a nested JS object of specific format and make a regex from it?

Regarding the inability to report violation line numbers, I think that is an acceptable tradeoff in the specific case of headings - because headings are simple to spot in documents. Alternatively, is there some way to pick apart the regex and at least state which headings are missing or incorrect (even if we can't determine line number)?

At the very least, we would need the ability to define a custom error message to point people at style guide in case of violations.

from markdownlint.

sagiegurari avatar sagiegurari commented on August 19, 2024

this is a really good feature.
when will this be published to npm?

from markdownlint.

DavidAnson avatar DavidAnson commented on August 19, 2024

I published version 0.2.0 a few minutes ago. :)

from markdownlint.

sagiegurari avatar sagiegurari commented on August 19, 2024

thanks

from markdownlint.

originalfoo avatar originalfoo commented on August 19, 2024

Been away due to RL issues, but great to see this feature implemented - many thanks!

from markdownlint.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.