Comments (12)
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.
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.
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.
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.
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.
Yes, good idea!
from markdownlint.
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.
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.
this is a really good feature.
when will this be published to npm?
from markdownlint.
I published version 0.2.0
a few minutes ago. :)
from markdownlint.
thanks
from markdownlint.
Been away due to RL issues, but great to see this feature implemented - many thanks!
from markdownlint.
Related Issues (20)
- MD056/table-column-count counts pipes inside backticks as column separators HOT 2
- MD014 only considers the `$` sign, is this intentional? HOT 2
- Umlauts like Ä, Ö, Ü in Mailadresses/URLs are not detected as normal letters HOT 5
- HTML disable/enables comments triggered when inside Markdown inline code HOT 4
- Frontmatter interpreted as top-level heading HOT 8
- `markdownlint-disable-next-line` should apply to the next non-empty line HOT 1
- MD045 shown when image has alt text in the optional title HOT 3
- MD029/ol-prefix: Continuous list with more than 10 elements HOT 1
- Include additional schema/types for strict rule name verification HOT 2
- Diabling rules from the front matter? HOT 2
- Reference links are lost between dollar signs HOT 7
- Feature Request: Recognize `markdownlint-*` configuration comments in "non-HTML comments" (unused link reference definitions) HOT 1
- MD036: doesn't fire when any HTML comment is present on the same line.
- MD018 error for ID selectors in inline CSS
- MD051 incorrectly expects lower cased fragment HOT 1
- Link fragments shows warning MD051 when target is preceeded by emoji. HOT 2
- MD010 no-hard-tabs rule is intended for indentation, but is triggered from any tabs HOT 1
- [Feature request] Disable auto correct on save for a specific rule? HOT 4
- [Feature Request] Checking Space around Embedded Code, Bold and Italic HOT 2
- [Proposal] Rule to disallow links in headings
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from markdownlint.