GithubHelp home page GithubHelp logo

markdownlint's Introduction

Markdown lint tool

Continuous Integration Gem Version

A tool to check markdown files and flag style issues.

Installation

Markdownlint is packaged in some distributions as well as distributed via RubyGems. Check the list below to see if it's packaged for your distribution, and if so, feel free to use your distros package manager to install it.

Packaging status

To install from rubygems, run:

gem install mdl

Alternatively you can build it from source:

git clone https://github.com/markdownlint/markdownlint
cd markdownlint
rake install

Note that you will need rake (gem install rake) and bundler (gem install bundler) in order to build from source.

Usage

To have markdownlint check your markdown files, simply run mdl with the filenames as a parameter:

mdl README.md

Markdownlint can also take a directory, and it will scan all markdown files within the directory (and nested directories):

mdl docs/

If you don't specify a filename, markdownlint will use stdin:

cat foo.md | mdl

Markdownlint will output a list of issues it finds, and the line number where the issue is. See RULES.md for information on each issue, as well as how to correct it:

README.md:1: MD013 Line length
README.md:70: MD029 Ordered list item prefix
README.md:71: MD029 Ordered list item prefix
README.md:72: MD029 Ordered list item prefix
README.md:73: MD029 Ordered list item prefix

Markdownlint has many more options you can pass on the command line, run mdl --help to see what they are, or see the documentation on configuring markdownlint.

Styles

Not everyone writes markdown in the same way, and there are multiple flavors and styles, each of which are valid. While markdownlint's default settings will result in markdown files that reflect the author's preferred markdown authoring preferences, your project may have different guidelines.

It's not markdownlint's intention to dictate any one specific style, and in order to support these differing styles and/or preferences, markdownlint supports what are called 'style files'. A style file is a file describing which rules markdownlint should enable, and also what settings to apply to individual rules. For example, rule MD013 checks for long lines, and by default will report an issue for any line longer than 80 characters. If your project has a different maximum line length limit, or if you don't want to enforce a line limit at all, then this can be configured in a style file.

For more information on creating style files, see the creating styles document.

Custom rules and rulesets

It may be that the rules provided in this project don't cover your stylistic needs. To account for this, markdownlint supports the creation and use of custom rules.

For more information, see the creating rules document.

Related projects

Contributing

See CONTRIBUTING.md for more information.

markdownlint's People

Contributors

adamstrickland avatar ajaust avatar ajorpheus avatar androidseb avatar apjanke avatar bquorning avatar davidanson avatar deivid-rodriguez avatar ericfromcanada avatar ffloyd avatar garthdb avatar jaymzh avatar jphastings avatar jwilk avatar lloeki avatar marquiz avatar mathroule avatar mivok avatar mjankowski avatar mkjaer avatar naomireeves avatar nbehrnd avatar olleolleolle avatar paulrbr avatar powerschill avatar psyomn avatar samiahmedsiddiqui avatar tas50 avatar totoroot avatar yo1995 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

markdownlint's Issues

Rule: List case and punctuation

From: http://www.************.com/markdown-styleguide/#case-of-first-letter-of-list-item

The style guide specifies rules based on grammar for whether to start the first letter of a list item with a capital letter and whether to end with punctuation or not. For the lint tool, we should just check a single list (and nested lists) for consistency. If the first item starts with a capital letter, they all should. If the first item ends with punctuation, they all should. Note: we should use the punctuation chars from #17 (or perhaps just pick sentence enders - !.?) to decide allowed punctuation.

This issue covers two separate rules.

Recursive search on Git tracked Markdown files.

Slightly off scope, but such an amazingly common use case.

Implementation: git ls-files, possibly through Grit or Rugged. This is important for GitLab, since the /tmp dir can contain many gitignore Markdown files: if not implemented here it will be definitely have to be implemented there.

Some files cause the tool to crash

I just ran our Markdown-based website through the tool and there are some files that cause the tool to crash. I observed the following exceptions:

undefined method `strip' for nil:NilClass -> markdownlint/lib/mdl/doc.rb:146:in `bullet_style'
undefined method `match' for nil:NilClass -> markdownlint/lib/mdl/doc.rb:163:in `indent_for'
undefined method `sub' for nil:NilClass -> markdownlint/lib/mdl/doc.rb:201:in `extract_text'
undefined method `start_with?' for nil:NilClass -> markdownlint/lib/mdl/doc.rb:126:in `header_style'
undefined method `empty?' for nil:NilClass -> markdownlint/lib/mdl/rules.rb:263:in `block (3 levels) in load'
undefined method `match' for nil:NilClass -> markdownlint/lib/mdl/rules.rb:305:in `block (3 levels) in load'

In these files:

/archived/accessibility_gitsvn_workflow.md
/archived/accessibility_moonlight_sandbox.md
/archived/accessibility_strongwind_basics.md
/archived/accessibility_team.md
/archived/accessibility_test_plan.md
/archived/accessibility_testing_howto.md
/archived/accessibility_uiaatkbridge.md
/archived/baseclass_provider_factory.md
/archived/buildsystem_monobuild_detaileddocs.md
/archived/buildsystem_packagingscripts.md
/archived/compiling_gtksharp.md
/archived/crimson.md
/archived/csharpplugin.md
/archived/db4o.md
/archived/gconftutorial.md
/archived/gettingstartedwithmonotools.md
/archived/howto_helloworld_moonlight_ff3.md
/archived/howto_mconfig.md
/archived/introduction_to_monoaddins.md
/archived/medlemmer.md
/archived/mono_a_technical_whitepaper.md
/archived/mono_summit_2007_session_list.md
/archived/monomacnew.md
/archived/monosummit2007.md
/archived/monotouch_xcode.md
/archived/moonlight_11_testsites.md
/archived/moonlight_securitystatus.md
/archived/moonlighthostingnotes.md
/archived/moonlightroadmap.md
/archived/moonlightsecurity.md
/archived/mugdenmark.md
/archived/old_visual_basic.md
/archived/other_downloads.md
/archived/outputfromconsoleapp.md
/archived/provider_factory.md
/archived/putty_and_tortoisesvn.md
/archived/racetolinux.md
/archived/repository.md
/archived/roadmap_history.md
/archived/stetic.md
/archived/systemmessaging.md
/archived/threadsbeginnersguide.md
/archived/use.md
/archived/winforms_designer.md
/archived/wpfnotes.md
/archived/xpathnavigator.md
/community/contributing/contribution-howto.md
/community/contributing/gitfaq.md
/community/contributing/index.md
/docs/about-mono/languages/cplusplus.md
/docs/about-mono/languages/ecma/ecma-335-publicdraft.md
/docs/about-mono/languages/ecma/index.md
/docs/about-mono/releases/1.0.1.md
/docs/about-mono/releases/2.10.0.md
/docs/about-mono/releases/2.4.2.1.md
/docs/about-mono/releases/2.4.2.2.md
/docs/about-mono/releases/2.4.2.3.md
/docs/about-mono/releases/2.4.2.md
/docs/about-mono/releases/3.0.0.md
/docs/about-mono/releases/3.2.7.md
/docs/about-mono/releases/3.4.0.md
/docs/about-mono/showcase/companies-using-mono.md
/docs/about-mono/showcase/software.md
/docs/advanced/cas.md
/docs/advanced/com-interop.md
/docs/advanced/coreclr.md
/docs/advanced/garbage-collector/sgen/index.md
/docs/advanced/runtime/docs/generic-sharing.md
/docs/advanced/runtime/docs/soft-debugger-wire-format.md
/docs/advanced/runtime/runtime-hacking.md
/docs/database-access/providers/postgresql.md
/docs/database-access/providers/sqlclient.md
/docs/gui/gtksharp/beginners-guide.md
/docs/gui/gtksharp/widgets/notification-icon.md
/docs/gui/winforms/porting-winforms-applications.md
/docs/tools+libraries/libraries/Mono.Cairo/index.md
/docs/tools+libraries/tools/gendarme/development-faq.md
/docs/tools+libraries/tools/gendarme/index.md
/docs/tools+libraries/tools/gendarme/roadmap.md
/docs/tools+libraries/tools/gendarme/rules/bad-practice.md
/docs/tools+libraries/tools/gendarme/rules/design-generic.md
/docs/tools+libraries/tools/gendarme/rules/design.md
/docs/tools+libraries/tools/gendarme/rules/exceptions.md
/docs/tools+libraries/tools/gendarme/rules/maintainability.md
/docs/tools+libraries/tools/gendarme/rules/performance.md
/docs/tools+libraries/tools/gendarme/rules/security-cas.md
/docs/tools+libraries/tools/gendarme/rules/serialization.md
/docs/tools+libraries/tools/gendarme/rules/smells.md
/docs/web/porting-aspnet-applications.md
/docs/web/wcf.md

The pages might contain some weird Markdown (most of them where converted by pandoc), but they render fine via Kramdown.

Rule: Header case

From: http://www.************.com/markdown-styleguide/#header-case

The guide specifies:

  • The first letter of a header should be capitalized
  • Except when the first word is a word that is never capitalized, such as 'int'.
  • Other letters shouldn't be capitalized except where they normally would be (e.g. proper names)
  • Title Case Should Not Be Used Except In Limited Circumstances

This rule seems a little difficult to implement fully and reliably (without implemented a grammer checker), but there may be a way to implement a simplified version (e.g. The first letter of headers should be capitalized) and allow exceptions to be specified.

Rule: Mixed horizontal rule styles

Detect inconsistent/mixed styles for HR. There are several. From the markdown spec:

You can produce a horizontal rule tag (<hr />) by placing three or more hyphens, asterisks, or underscores on a line by themselves. If you wish, you may use spaces between the hyphens or asterisks. Each of the following lines will produce a horizontal rule:

* * *

***

*****

- - -

---------------------------------------

I suspect that for the style itself, we will just capture the entire line. We probably want to check that the line matches ^[*-_\s]+$ first just in case some other HR style is used such as a html tag (and use unknown for a non-matching style).

Also add rules requiring a specific horizontal rule style, see http://www.************.com/markdown-styleguide/#horizontal-rules which recommends ---.

Rule: Line longer than 80 characters

From: http://www.************.com/markdown-styleguide/#line-wrapping

There will need to be some exceptions to this. One possibility is to allow lines longer that 80 characters, but only if there is no whitespace after the 80th character. This deals with the case where URLs are longer than 80 characters and there is no sensible place to break it up.

Another exception could be inside preformatted text blocks, where it's indented anyway and you might have pasted code that is longer than 80 characters. This one is easier to work around (format the code), so I'm less sure about this exception. The rule can be ignored anyway for people who want to use lines longer than 80 characters.

Rule: Spaces after list markers

From: http://www.************.com/markdown-styleguide/#spaces-after-marker

  • If the list item contains code blocks (or if it contains blank lines?), then there should be three spaces after an unordered list item, and two after an ordered list item.
  • If the list item doesn't contain code blocks (or blank lines?), then there should be just a single space after the list marker.

The reason for this is to work around a 'bug' in kramdown where code blocks end up indented by two spaces if you only have a single space and then indent twice to get a code block.

I'm unsure whether I want this rule to be enabled by default or not.

Rule: detect code blocks that aren't

This rule is an attempt to detect when the document creator intended to create a code block, but didn't do it correctly, and so the text would be rendered as normal text by the parser.

Example:

  • No blank line before the code block
  • Not enough indentation before the code block

We need to detect list items that weren't rendered as code blocks, but which have multiple lines and an indentation that suggests a code block was indented (e.g. 4 space indent).

This rule may need several variations as different parsers render code blocks differently: See http://www.************.com/markdown-styleguide/#rationale-why-not-always-single-space for some examples.

Configuration file

Allow options on the command line to also be specified in a configuration file to allow specific sets of rules to be checked.

Inline 'ignore rule' functionality

Allow specific rule violations to be ignored in the document itself. The mechanism for this:

  • Should not appear in the rendered document
  • Should optionally allow a specific rule ID to be mentioned
  • Should go on the same line where the rule violation occurred, if possible
  • Should also be able to go at the end of the file, specifying a line number (for cases where it's not possible to put the ignore tag on the same line)

A possible implementation of this: Kramdown extensions: {::ignore rule="MDXXX" line="1" /} (rule and line are both options, so {::ignore} would work. See http://kramdown.gettalong.org/syntax.html#extensions.

For other parsers that don't support the extension, the ignore would have to be commented out using HTML comments or some other comment mechanism. We may also wish to support an alternative ignore syntax for these cases that allows ignores directly in the comments, for example <!-- ::ignore ... -->

Support per-project style files

Rubocop supports .rubocop.yml files inside a project dir (and parent dirs). We should support the same thing to allow projects to set their own style. In addition, we need to come up with a nice way to include other styles - both relative to the current style file and relative to the built in styles.

Rule: Surround lists by empty lines

From: http://www.************.com/markdown-styleguide/#lists-and-empty-lines

  • Top level lists should have empty lines around them
  • Nested lists should have empty lines around them, except if both the outer list and inner list don't have blank lines separating the items.

When implementing this rule, look to see what is generated for lists with blank lines in them. The style guide says a

is generated and this should allow for an easy way to detect the list style.

Named rule sets/style files

Provide support for user-configurable sets of rules that are to be checked by default. These rule sets can specify tags to include, tags to exclude, and rules to include/exclude. This will allow simple configuration of rules to enable/disable to match specific styles, as well as allowing markdownlint to provide some defaults for various styles.

Rule: Inconsistent spacing inside closed-atx style header

In documents that use ## Closed ATX style headers ##, check that the number of spaces between the # symbols and the header text match on both sides (ideally it should just be one space, but another rule will take care of that).

This isn't referenced in http://www.************.com/markdown-styleguide because that guide recommends against the use of the closing symbol on atx-style headers, but is similar to other recommendations made for atx style headers in that guide.

Rule: Multiple top level headers in file

From: http://www.************.com/markdown-styleguide/#top-level-header

A top level header should be a h1, on the first line of the file, and there should be no other h1 headers in the file.

We should check that: if the first line in the file is a h1 header, then there should be no other h1 headers in the file.

If the first line isn't a h1 header, then there isn't a top level header in the file and this rule wouldn't then apply.

A potential problem/fix needed: I use 'top level header' in MD002 to mean 'h1'. This should be changed when this rule is implemented to not confuse what is meant by a top level header.

Use human readable key value pairs for configuration.

Instead of the MDXXX ids, why don't we use human readable key value pairs like:

unordered_list_marker: '*'

Advantages:

  • human readable: people can just read the config file directly to determine the style. Currently, you would have to look up what every rule means, or use comments, which generates a lot of explanation. Same reason why we use nice var names in the code.
  • pairs: deal nicely with mutually exclusive options like choosing one header or list style, in which enforcing multiple rules should never be done. Would solve: #38

Disadvantage: longer to type. But this is not serious, since projects will write a config file and seldom modify it, and for interactive use according to personal preferences one can just alias it or we can add a global config. Being able to read quickly is more important in this case.

This is what the popular Rubocop does: https://github.com/bbatsov/rubocop/blob/master/config/default.yml.

This could be implemented in either Ruby or YAML: I'd rather have YAML since it allows us not to write rule directives all the time and since the config is mostly static, but this is no big deal.

Also once we fix those things we should document it. I had to Google and grep a bit to figure it out =) #41

Option to show the list of enabled rules

Add an option that, instead of checking files, just lists the rules that are enabled with the current settings (i.e. style file, config file options and command line options). Without the verbose option, it should just print the rule IDs. With the verbose option it should print the names also.

Rule: Blank lines in between list items

From: http://www.************.com/markdown-styleguide/#lists-and-empty-lines

(Edit: the link is now http://www.************.com/markdown-style-guide/#empty-lines-inside-lists )

The style guide actually specifies that there should always be blank lines between all list items in a given list, or there should be no blank lines in between list items. We should check a document for inconsistent list separation. Note: This is just inconsistency within a single list (and not even in nested lists), not across the entire document.

See also #26 and #27 for list blank line rules, as well as a possibility for detecting list separation style.

My original thinking behind the rule was attempting to separate two lists by a single blank line, and them being rendered as a single list, which wouldn't be what the document author apparently intended. However, detecting the document style and reporting inconsistency works also. The documentation of the rule should explain that blank lines in between list items doesn't separate lists as well as referring to the style guide.

Warn when conflicting rules enabled

Add a 'conflicts_with' attribute to rules, and show a warning if conflicting rules are enabled (Make it a fatal error, but allow it to be overridden with a command line option).

There should probably also be some dedup logic in there, so if MD123 conflicts with MD124, and MD124 conflicts with MD123 (because I was diligent and put the conflicts_with entry on both rules), then the error message doesn't show up twice.

Rule: Blank line inside same blockquote

From: http://www.************.com/markdown-styleguide/#blockquotes

The style guide says that the same quote shouldn't have blank lines in:

> Some quote
>
> Good, a quote symbol is used

> Some quote

> Bad, the same quote has a blank line separating it.

I suspect this won't be possible to check for, depending on whether blank lines in between block quotes cause them to be separate quotes or not. It won't be possible to see if someone was trying to do two different quotes one after the other, or if it was the same quote.

Additional style files

Some ideas:

  • ************ (adherence to the style guide there)
  • relaxed (disable all rules that enforce a specific style - i.e. only use atx headers, no hard tabs, 80 column lines)
  • default (mark's personal ruleset)

Make some others based on specific styles that modify the relaxed ones (perhaps allow a style to include another - it's ruby so just require 'foo')

Document all existing rules

Add documentation, links and rationales to all existing rules. This should be done inline.

Add a documentation generator script to generate the actual documentation from the rules file.

The generator should print out the tags, as well as any conflicting rules (see #38).

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.