diff --git a/.eslintrc.json b/.eslintrc.json
index eeb60e8d..48d362a9 100644
--- a/.eslintrc.json
+++ b/.eslintrc.json
@@ -5,8 +5,69 @@
"node": true
},
"rules": {
+ "accessor-pairs": "error",
+ "array-bracket-spacing": ["error", "always"],
+ "array-callback-return": "error",
+ "arrow-body-style": "error",
+ "arrow-parens": "error",
+ "arrow-spacing": "error",
+ "block-scoped-var": "error",
+ "block-spacing": "error",
+ "brace-style": "error",
+ "callback-return": "off",
+ "camelcase": "error",
+ "capitalized-comments": "off",
+ "class-methods-use-this": "error",
+ "comma-dangle": "error",
+ "comma-spacing": "error",
+ "comma-style": "error",
+ "complexity": "error",
+ "computed-property-spacing": "error",
+ "consistent-return": "off",
+ "consistent-this": "error",
+ "constructor-super": "error",
+ "curly": "error",
+ "default-case": "error",
+ "dot-location": ["error", "property"],
+ "dot-notation": "error",
+ "eol-last": "error",
+ "eqeqeq": "error",
+ "func-call-spacing": "error",
+ "func-name-matching": "off",
+ "func-names": "error",
+ "func-style": ["error", "declaration"],
+ "generator-star-spacing": "error",
+ "global-require": "off",
+ "guard-for-in": "error",
+ "handle-callback-err": "error",
+ "id-blacklist": "error",
+ "id-length": "off",
+ "id-match": "error",
+ "indent": ["error", 2, { "SwitchCase": 1 }],
+ "init-declarations": "error",
+ "jsx-quotes": "error",
+ "key-spacing": "error",
+ "keyword-spacing": "error",
+ "line-comment-position": "error",
+ "linebreak-style": "off",
+ "lines-around-comment": "off",
+ "lines-around-directive": "error",
+ "max-depth": "error",
+ "max-len": "error",
+ "max-lines": "off",
+ "max-nested-callbacks": "error",
+ "max-params": ["error", 6],
+ "max-statements": ["error", 28],
+ "max-statements-per-line": "error",
+ "multiline-ternary": "off",
+ "new-cap": "error",
+ "new-parens": "error",
+ "newline-after-var": "off",
+ "newline-before-return": "off",
+ "newline-per-chained-call": "off",
"no-alert": "error",
"no-array-constructor": "error",
+ "no-await-in-loop": "error",
"no-bitwise": "off",
"no-caller": "error",
"no-case-declarations": "error",
@@ -63,6 +124,7 @@
"no-mixed-operators": "error",
"no-mixed-requires": "error",
"no-mixed-spaces-and-tabs": "error",
+ "no-multi-assign": "off",
"no-multi-spaces": "error",
"no-multi-str": "error",
"no-multiple-empty-lines": "error",
@@ -101,20 +163,20 @@
"no-sequences": "error",
"no-shadow": "error",
"no-shadow-restricted-names": "error",
- "no-whitespace-before-property": "error",
"no-spaced-func": "error",
"no-sparse-arrays": "error",
"no-sync": "off",
"no-tabs": "error",
+ "no-template-curly-in-string": "error",
"no-ternary": "off",
- "no-trailing-spaces": "error",
"no-this-before-super": "error",
"no-throw-literal": "error",
+ "no-trailing-spaces": "error",
"no-undef": "error",
"no-undef-init": "error",
"no-undefined": "off",
- "no-unexpected-multiline": "error",
"no-underscore-dangle": "error",
+ "no-unexpected-multiline": "error",
"no-unmodified-loop-condition": "error",
"no-unneeded-ternary": "error",
"no-unreachable": "error",
@@ -131,69 +193,11 @@
"no-useless-escape": "error",
"no-useless-rename": "error",
"no-useless-return": "error",
- "no-void": "error",
"no-var": "off",
+ "no-void": "error",
"no-warning-comments": "error",
+ "no-whitespace-before-property": "error",
"no-with": "error",
- "array-bracket-spacing": ["error", "always"],
- "array-callback-return": "error",
- "arrow-body-style": "error",
- "arrow-parens": "error",
- "arrow-spacing": "error",
- "accessor-pairs": "error",
- "block-scoped-var": "error",
- "block-spacing": "error",
- "brace-style": "error",
- "callback-return": "off",
- "camelcase": "error",
- "class-methods-use-this": "error",
- "comma-dangle": "error",
- "comma-spacing": "error",
- "comma-style": "error",
- "complexity": "error",
- "computed-property-spacing": "error",
- "consistent-return": "off",
- "consistent-this": "error",
- "constructor-super": "error",
- "curly": "error",
- "default-case": "error",
- "dot-location": ["error", "property"],
- "dot-notation": "error",
- "eol-last": "error",
- "eqeqeq": "error",
- "func-call-spacing": "error",
- "func-names": "error",
- "func-name-matching": "off",
- "func-style": ["error", "declaration"],
- "generator-star-spacing": "error",
- "global-require": "off",
- "guard-for-in": "error",
- "handle-callback-err": "error",
- "id-blacklist": "error",
- "id-length": "off",
- "id-match": "error",
- "indent": ["error", 2, { "SwitchCase": 1 }],
- "init-declarations": "error",
- "jsx-quotes": "error",
- "key-spacing": "error",
- "keyword-spacing": "error",
- "linebreak-style": "off",
- "line-comment-position": "error",
- "lines-around-comment": "off",
- "lines-around-directive": "error",
- "max-depth": "error",
- "max-len": "error",
- "max-lines": "off",
- "max-nested-callbacks": "error",
- "max-params": ["error", 6],
- "max-statements": ["error", 28],
- "max-statements-per-line": "error",
- "multiline-ternary": "off",
- "new-cap": "error",
- "new-parens": "error",
- "newline-after-var": "off",
- "newline-before-return": "off",
- "newline-per-chained-call": "off",
"object-curly-newline": "off",
"object-curly-spacing": ["error", "always"],
"object-property-newline": "error",
@@ -205,7 +209,9 @@
"padded-blocks": "off",
"prefer-arrow-callback": "off",
"prefer-const": "off",
+ "prefer-destructuring": "off",
"prefer-numeric-literals": "error",
+ "prefer-promise-reject-errors": "error",
"prefer-reflect": "off",
"prefer-rest-params": "off",
"prefer-spread": "off",
@@ -213,13 +219,14 @@
"quote-props": "error",
"quotes": "error",
"radix": "error",
+ "require-await": "error",
"require-jsdoc": "off",
"require-yield": "error",
"rest-spread-spacing": "error",
"semi": "error",
"semi-spacing": "error",
- "sort-keys": "off",
"sort-imports": "error",
+ "sort-keys": "off",
"sort-vars": "error",
"space-before-blocks": "error",
"space-before-function-paren": ["error", "never"],
@@ -230,6 +237,7 @@
"strict": "error",
"symbol-description": "error",
"template-curly-spacing": "error",
+ "template-tag-spacing": "error",
"unicode-bom": "error",
"use-isnan": "error",
"valid-jsdoc": "error",
@@ -237,7 +245,6 @@
"vars-on-top": "off",
"wrap-iife": "error",
"wrap-regex": "off",
- "no-template-curly-in-string": "error",
"yield-star-spacing": "error",
"yoda": "error"
}
diff --git a/LICENSE b/LICENSE
index 576a5e0f..c6a0b942 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
The MIT License (MIT)
-Copyright (c) 2015-2016 David Anson
+Copyright (c) 2015-2017 David Anson
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/README.md b/README.md
index 99b5f0bc..47e83cf2 100644
--- a/README.md
+++ b/README.md
@@ -84,6 +84,7 @@ playground for learning and exploring.
* **MD041** *first-line-h1* - First line in file should be a top level header
* **MD042** *no-empty-links* - No empty links
* **MD043** *required-headers* - Required header structure
+* **MD044** *proper-names* - Proper names should have the correct capitalization
See [Rules.md](doc/Rules.md) for more details.
@@ -107,6 +108,7 @@ See [Rules.md](doc/Rules.md) for more details.
* **links** - MD011, MD034, MD039, MD042
* **ol** - MD029, MD030, MD032
* **spaces** - MD018, MD019, MD020, MD021, MD023
+* **spelling** - MD044
* **ul** - MD004, MD005, MD006, MD007, MD030, MD032
* **url** - MD034
* **whitespace** - MD009, MD010, MD012, MD027, MD028, MD030, MD037, MD038, MD039
diff --git a/demo/default.htm b/demo/default.htm
index 14548fe3..114073aa 100644
--- a/demo/default.htm
+++ b/demo/default.htm
@@ -28,7 +28,7 @@
diff --git a/doc/Rules.md b/doc/Rules.md
index fc161d3d..a0edafd0 100644
--- a/doc/Rules.md
+++ b/doc/Rules.md
@@ -334,7 +334,7 @@ Tags: line_length
Aliases: line-length
-Parameters: line_length, code_blocks, tables (number; default 80, boolean; default true)
+Parameters: line_length, code_blocks, tables, headers (number; default 80, boolean; default true)
This rule is triggered when there are lines that are longer than the
configured line length (default: 80 characters). To fix this, split the line
@@ -344,8 +344,8 @@ This rule has an exception where there is no whitespace beyond the configured
line length. This allows you to still include items such as long URLs without
being forced to break them in the middle.
-You also have the option to exclude this rule for code blocks and tables. To
-do this, set the `code_blocks` and/or `tables` parameters to false.
+You have the option to exclude this rule for code blocks, tables, or headers.
+To do so, set the `code_blocks`, `tables`, or `headers` parameter(s) to false.
Code blocks are included in this rule by default since it is often a
requirement for document readability, and tentatively compatible with code
@@ -986,6 +986,11 @@ To fix this, remove the spaces inside the codespan markers:
`some text`
+Note: A single leading or trailing space is allowed if used to separate codespan
+markers from an embedded backtick:
+
+ `` ` embedded backtick``
+
## MD039 - Spaces inside link text
Tags: whitespace, links
@@ -1032,17 +1037,13 @@ Parameters: level (number; default 1)
This rule is triggered when the first line in the file isn't a top level (h1)
header:
- ```
This is a file without a header
- ```
To fix this, add a header to the top of your file:
- ```
# File with header
This is a file with a top level header
- ```
Note: The `level` parameter can be used to change the top level (ex: to h2) in
cases where an h1 is added externally.
@@ -1119,3 +1120,23 @@ problematic header (otherwise, it outputs the last line number of the file).
Note that while the `headers` parameter uses the "## Text" ATX header style for
simplicity, a file may use any supported header style.
+
+## MD044 - Proper names should have the correct capitalization
+
+Tags: spelling
+
+Aliases: proper-names
+
+Parameters: names (array of string; default `null` for disabled)
+
+This rule is triggered when any of the strings in the `names` array do not have
+the specified capitalization. It can be used to enforce a standard letter case
+for the names of projects and products.
+
+For example, the language "JavaScript" is usually written with both the 'J' and
+'S' capitalized - though sometimes the 's' or 'j' appear in lower-case. To enforce
+the proper capitalization, specify the desired letter case in the `names` array:
+
+ [
+ "JavaScript"
+ ]
diff --git a/lib/rules.js b/lib/rules.js
index a2d000f9..f77e0b8e 100644
--- a/lib/rules.js
+++ b/lib/rules.js
@@ -8,9 +8,10 @@ var atxClosedHeaderSpaceRe = /(?:^#+\s\s+?\S)|(?:\S\s\s+?#+\s*$)/;
var atxHeaderSpaceRe = /^#+\s*\S/;
var bareUrlRe = /(?:http|ftp)s?:\/\/[^\s]*/;
var dollarCommandRe = /^(\s*)(\$\s)/;
-var emptyLinkRe = /\[[^\]]*](?=(?:\((?:#?|(?:<>))\))|(?:\[[^\]]*]))/;
+var emptyLinkRe = /\[[^\]]*](?:\((?:#?|(?:<>))\))|(?:\[[^\]]*])/;
var htmlRe = /<[^>]*>/;
var listItemMarkerRe = /^[\s>]*(?:[*+-]|\d+\.)\s+/;
+var listItemMarkerInterruptsRe = /^[\s>]*(?:[*+-]|1\.)\s+/;
var reversedLinkRe = /\([^)]+\)\[[^\]^][^\]]*]/;
var spaceAfterBlockQuote = />\s+\S/;
var spaceBeforeHeaderRe = /^\s+\S/;
@@ -55,7 +56,7 @@ function unorderedListStyleFor(token) {
return "dash";
case "+":
return "plus";
- case "*":
+ // case "*":
default:
return "asterisk";
}
@@ -426,13 +427,34 @@ module.exports = [
var includeCodeBlocks = (codeBlocks === undefined) ? true : !!codeBlocks;
var tables = params.options.tables;
var includeTables = (tables === undefined) ? true : !!tables;
- var re = longLineReFunc(params.options);
+ var headers = params.options.headers;
+ var includeHeaders = (headers === undefined) ? true : !!headers;
+ var headerLineNumbers = [];
+ if (!includeHeaders) {
+ forEachHeading(params, function forHeading(heading) {
+ headerLineNumbers.push(heading.lineNumber);
+ });
+ }
+ var linkOnlyLineNumbers = [];
+ filterTokens(params, "inline", function forToken(token) {
+ if (((token.children.length === 2) || (token.children.length === 3)) &&
+ (token.children[0].type === "link_open") &&
+ (token.children[token.children.length - 1].type === "link_close")) {
+ linkOnlyLineNumbers.push(token.lineNumber);
+ }
+ });
+ var longLineRe = longLineReFunc(params.options);
+ var labelRe = /^\s*\[.*[^\\]]:/;
forEachLine(params,
function forLine(line, lineIndex, inCode, onFence, inTable) {
+ var lineNumber = lineIndex + 1;
if ((includeCodeBlocks || !inCode) &&
(includeTables || !inTable) &&
- re.test(line)) {
- errors.addDetailIf(lineIndex + 1, lineLength, line.length);
+ (includeHeaders || (headerLineNumbers.indexOf(lineNumber)) < 0) &&
+ (linkOnlyLineNumbers.indexOf(lineNumber) < 0) &&
+ longLineRe.test(line) &&
+ !labelRe.test(line)) {
+ errors.addDetailIf(lineNumber, lineLength, line.length);
}
});
}
@@ -774,7 +796,12 @@ module.exports = [
var lineTrim = line.trim();
var listMarker = listItemMarkerRe.test(lineTrim);
if (listMarker && !inList && !blankOrListRe.test(prevLine)) {
- errors.addContext(lineIndex + 1, lineTrim);
+ // Check whether this list prefix can interrupt a paragraph
+ if (listItemMarkerInterruptsRe.test(lineTrim)) {
+ errors.addContext(lineIndex + 1, lineTrim);
+ } else {
+ listMarker = false;
+ }
} else if (!listMarker && inList && !blankOrListRe.test(line)) {
errors.addContext(lineIndex, lineTrim);
}
@@ -931,20 +958,19 @@ module.exports = [
"aliases": [ "no-space-in-code" ],
"regexp": spaceInsideCodeRe,
"func": function MD038(params, errors) {
+ var inlineCodeSpansRe = /(`+)((?:.*?[^`])|)\1(?!`)/g;
forEachInlineChild(params, "code_inline",
- function forToken(token, inline) {
- var backtickPairs = "^(?:[^`]*`[^`]*`)*[^`]*";
- var escapedContent = escapeForRegExp(token.content);
- var left = (new RegExp(
- backtickPairs + "(`\\s+" + escapedContent + "\\s*`)"))
- .exec(inline.content);
- var right = (new RegExp(
- backtickPairs + "(`\\s*" + escapedContent + "\\s+`)"))
- .exec(inline.content);
- if (left) {
- errors.addContext(token.lineNumber, left[1]);
- } else if (right) {
- errors.addContext(token.lineNumber, right[1], false, true);
+ function forToken(token) {
+ var line = params.lines[token.lineNumber - 1];
+ var match = null;
+ while ((match = inlineCodeSpansRe.exec(line)) !== null) {
+ var inlineCodeSpan = match[0];
+ var content = match[2];
+ if (/^\s([^`]|$)/.test(content)) {
+ errors.addContext(token.lineNumber, inlineCodeSpan);
+ } else if (/[^`]\s$/.test(content)) {
+ errors.addContext(token.lineNumber, inlineCodeSpan, false, true);
+ }
}
});
}
@@ -1004,21 +1030,19 @@ module.exports = [
"func": function MD041(params, errors) {
var level = params.options.level || 1;
var tag = "h" + level;
- var firstHeader = null;
- params.tokens.every(function forToken(token) {
+ params.tokens.every(function forToken(token, index) {
if (token.type === "heading_open") {
- firstHeader = token;
- return false;
- } else if (token.lineNumber > 1) {
+ if (!((token.lineNumber === 1) || (index > 0)) ||
+ (token.tag !== tag)) {
+ errors.addContext(token.lineNumber, token.line);
+ }
return false;
+ } else if (token.type === "html_block") {
+ return true;
}
- return true;
+ errors.addContext(token.lineNumber, token.line);
+ return false;
});
- if (!firstHeader ||
- (firstHeader.lineNumber !== 1) ||
- (firstHeader.tag !== tag)) {
- errors.addContext(1, params.lines[0]);
- }
}
},
@@ -1073,7 +1097,7 @@ module.exports = [
forEachHeading(params, function forHeading(heading, content) {
if (!errors.length) {
var actual = levels[heading.tag] + " " + content;
- var expected = requiredHeaders[i++] || "";
+ var expected = requiredHeaders[i++] || "[None]";
if (expected === "*") {
optional = true;
} else if (expected.toLowerCase() === actual.toLowerCase()) {
@@ -1090,5 +1114,27 @@ module.exports = [
}
}
}
+ },
+
+ {
+ "name": "MD044",
+ "desc": "Proper names should have the correct capitalization",
+ "tags": [ "spelling" ],
+ "aliases": [ "proper-names" ],
+ "regexp": null,
+ "func": function MD044(params, errors) {
+ var names = params.options.names || [];
+ names.forEach(function forName(name) {
+ var escapedName = escapeForRegExp(name);
+ var namePattern = "\\b" + escapedName + "\\b";
+ var anyNameRe = new RegExp(namePattern, "gi");
+ forEachLine(params, function forLine(line, lineIndex) {
+ var matches = line.match(anyNameRe) || [];
+ matches.forEach(function forMatch(match) {
+ errors.addDetailIf(lineIndex + 1, name, match);
+ });
+ });
+ });
+ }
}
];
diff --git a/package.json b/package.json
index 0de21663..306164ab 100644
--- a/package.json
+++ b/package.json
@@ -23,19 +23,19 @@
"example": "cd example && node standalone.js && grunt markdownlint --force && gulp markdownlint"
},
"dependencies": {
- "markdown-it": "^8.0.1"
+ "markdown-it": "^8.3.0"
},
"devDependencies": {
- "browserify": "^13.1.1",
+ "browserify": "^14.1.0",
"cpy-cli": "^1.0.1",
- "eslint": "^3.10.0",
+ "eslint": "^3.16.1",
"glob": "^7.1.1",
"istanbul": "^0.4.5",
- "nodeunit": "^0.10.2",
+ "nodeunit": "^0.11.0",
"q": "^1.4.1",
- "rimraf": "^2.5.4",
+ "rimraf": "^2.6.1",
"tv4": "^1.2.7",
- "uglify-js": "^2.7.4"
+ "uglify-js": "^2.8.5"
},
"keywords": [
"markdown",
diff --git a/schema/build-config-schema.js b/schema/build-config-schema.js
index 873c3acd..9d0c05f1 100644
--- a/schema/build-config-schema.js
+++ b/schema/build-config-schema.js
@@ -129,6 +129,11 @@ rules.forEach(function forRule(rule) {
"description": "Include tables",
"type": "boolean",
"default": true
+ },
+ "headers": {
+ "description": "Include headers",
+ "type": "boolean",
+ "default": true
}
};
break;
@@ -212,6 +217,18 @@ rules.forEach(function forRule(rule) {
}
};
break;
+ case "MD044":
+ scheme.properties = {
+ "names": {
+ "description": "List of proper names",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "default": null
+ }
+ };
+ break;
default:
custom = false;
break;
diff --git a/schema/markdownlint-config-schema.json b/schema/markdownlint-config-schema.json
index 87859dfb..a83ee102 100644
--- a/schema/markdownlint-config-schema.json
+++ b/schema/markdownlint-config-schema.json
@@ -323,6 +323,11 @@
"description": "Include tables",
"type": "boolean",
"default": true
+ },
+ "headers": {
+ "description": "Include headers",
+ "type": "boolean",
+ "default": true
}
},
"additionalProperties": false
@@ -349,6 +354,11 @@
"description": "Include tables",
"type": "boolean",
"default": true
+ },
+ "headers": {
+ "description": "Include headers",
+ "type": "boolean",
+ "default": true
}
},
"additionalProperties": false
@@ -871,6 +881,44 @@
},
"additionalProperties": false
},
+ "MD044": {
+ "description": "MD044/proper-names - Proper names should have the correct capitalization",
+ "type": [
+ "boolean",
+ "object"
+ ],
+ "default": true,
+ "properties": {
+ "names": {
+ "description": "List of proper names",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "default": null
+ }
+ },
+ "additionalProperties": false
+ },
+ "proper-names": {
+ "description": "MD044/proper-names - Proper names should have the correct capitalization",
+ "type": [
+ "boolean",
+ "object"
+ ],
+ "default": true,
+ "properties": {
+ "names": {
+ "description": "List of proper names",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "default": null
+ }
+ },
+ "additionalProperties": false
+ },
"headers": {
"description": "headers - MD001, MD002, MD003, MD018, MD019, MD020, MD021, MD022, MD023, MD024, MD025, MD026, MD036, MD041, MD043",
"type": "boolean",
@@ -970,6 +1018,11 @@
"description": "language - MD040",
"type": "boolean",
"default": true
+ },
+ "spelling": {
+ "description": "spelling - MD044",
+ "type": "boolean",
+ "default": true
}
},
"additionalProperties": false
diff --git a/test/break-all-the-rules.json b/test/break-all-the-rules.json
index cd5d749d..9f200f6b 100644
--- a/test/break-all-the-rules.json
+++ b/test/break-all-the-rules.json
@@ -7,5 +7,10 @@
"#### Header 2 {MD001}",
"# Broken"
]
+ },
+ "MD044": {
+ "names": [
+ "markdownlint"
+ ]
}
}
diff --git a/test/break-all-the-rules.md b/test/break-all-the-rules.md
index b832885e..ae037f08 100644
--- a/test/break-all-the-rules.md
+++ b/test/break-all-the-rules.md
@@ -75,3 +75,5 @@ code fence without language {MD040:73}
```
[empty link]() {MD042}
+
+markdownLint {MD044}
diff --git a/test/detailed-results-MD041-MD043.md b/test/detailed-results-MD041-MD043.md
deleted file mode 100644
index 985d782d..00000000
--- a/test/detailed-results-MD041-MD043.md
+++ /dev/null
@@ -1,3 +0,0 @@
-Not a header
-
-An [empty]() link
diff --git a/test/detailed-results-MD041-MD043.json b/test/detailed-results-MD041-MD050.json
similarity index 61%
rename from test/detailed-results-MD041-MD043.json
rename to test/detailed-results-MD041-MD050.json
index 7b669757..e6ba034d 100644
--- a/test/detailed-results-MD041-MD043.json
+++ b/test/detailed-results-MD041-MD050.json
@@ -5,5 +5,10 @@
"headers": [
"# Header"
]
+ },
+ "MD044": {
+ "names": [
+ "markdownlint"
+ ]
}
}
diff --git a/test/detailed-results-MD041-MD050.md b/test/detailed-results-MD041-MD050.md
new file mode 100644
index 00000000..b564c98e
--- /dev/null
+++ b/test/detailed-results-MD041-MD050.md
@@ -0,0 +1,7 @@
+Not a header
+
+An [empty]() link
+
+An [empty](#) link with fragment
+
+This is a test file for the MARKDOWNLINT package.
diff --git a/test/detailed-results-MD041-MD043.results.json b/test/detailed-results-MD041-MD050.results.json
similarity index 54%
rename from test/detailed-results-MD041-MD043.results.json
rename to test/detailed-results-MD041-MD050.results.json
index 1b90f8d3..1f7f19fd 100644
--- a/test/detailed-results-MD041-MD043.results.json
+++ b/test/detailed-results-MD041-MD050.results.json
@@ -15,15 +15,33 @@
"ruleDescription": "No empty links",
"errorDetail": null,
"errorContext": "[empty]",
- "errorRange": [4, 7]
+ "errorRange": [4, 9]
},
{
- "lineNumber": 4,
+ "lineNumber": 5,
+ "ruleName": "MD042",
+ "ruleAlias": "no-empty-links",
+ "ruleDescription": "No empty links",
+ "errorDetail": null,
+ "errorContext": "[empty]",
+ "errorRange": [4, 10]
+ },
+ {
+ "lineNumber": 8,
"ruleName": "MD043",
"ruleAlias": "required-headers",
"ruleDescription": "Required header structure",
"errorDetail": null,
"errorContext": "# Header",
"errorRange": null
+ },
+ {
+ "lineNumber": 7,
+ "ruleName": "MD044",
+ "ruleAlias": "proper-names",
+ "ruleDescription": "Proper names should have the correct capitalization",
+ "errorDetail": "Expected: markdownlint; Actual: MARKDOWNLINT",
+ "errorContext": null,
+ "errorRange": null
}
]
\ No newline at end of file
diff --git a/test/list-syntax-in-paragraph-text.md b/test/list-syntax-in-paragraph-text.md
new file mode 100644
index 00000000..0c9a685f
--- /dev/null
+++ b/test/list-syntax-in-paragraph-text.md
@@ -0,0 +1,37 @@
+# Heading
+
+This paragraph has the number
+5. More text.
+
+This paragraph has the number
+11. More text.
+
+This non-paragraph has the number
+1. This is a list. {MD032}
+
+This non-paragraph has the number
+1. This is a list. It also has the number {MD032}
+5. This is a list. {MD029}
+
+This non-paragraph has spaces and the number
+1. This is a list. {MD030} {MD032}
+
+This non-paragraph has a dash
+- in its list. {MD032}
+
+This non-paragraph has a dash
+- in its list. It also has a plus {MD032}
++ in its list. {MD004}
+
+This non-paragraph has spaces and a dash
+- This is a list. {MD030} {MD032}
+
+This is a mixed paragraph that has
+2. followed by text followed by
+1. which creates a list {MD032}
+1. with a couple of items
+
+Another mixed paragraph
+2. with more text
+in the middle of things
+1. before the list {MD032}
diff --git a/test/lists_without_blank_lines.md b/test/lists_without_blank_lines.md
index b1571966..4de1221b 100644
--- a/test/lists_without_blank_lines.md
+++ b/test/lists_without_blank_lines.md
@@ -19,8 +19,8 @@ text
text
text
-10. list {MD032}
-20. list
+1. list {MD032}
+2. list
text
diff --git a/test/long-header-exceptions.json b/test/long-header-exceptions.json
new file mode 100644
index 00000000..6af9f257
--- /dev/null
+++ b/test/long-header-exceptions.json
@@ -0,0 +1,6 @@
+{
+ "default": true,
+ "MD013": {
+ "headers": false
+ }
+}
diff --git a/test/long-header-exceptions.md b/test/long-header-exceptions.md
new file mode 100644
index 00000000..ce5dba99
--- /dev/null
+++ b/test/long-header-exceptions.md
@@ -0,0 +1,21 @@
+# Header
+
+Text
+
+## Header header header header header header header header header header header header header header header header
+
+Text
+
+Text text text text text text text text text text text text text text text text text text text text text text text text {MD013}
+
+## Header header
+
+Text
+
+Text text text text text text text text text text text text text text text text text text text text text text text text {MD013}
+
+### Header header header header header header header header header header header header header header header header header
+
+Text
+
+Text text text text text text text text text text text text text text text text text text text text text text text text {MD013}
diff --git a/test/long_lines.md b/test/long_lines.md
index 875c8c69..94ae56af 100644
--- a/test/long_lines.md
+++ b/test/long_lines.md
@@ -1,3 +1,23 @@
This is a very very very very very very very very very very very very very very long line {MD013}
-This line however, while very long, doesn't have whitespace after the 80th columnwhichallowsforURLsandotherlongthings.
\ No newline at end of file
+This line however, while very long, doesn't have whitespace after the 80th columnwhichallowsforURLsandotherlongthings.
+
+[This long line is comprised entirely of a link](http://example.com "This is the long link's title")
+
+> [This long line is comprised entirely of a link](http://example.com "This is the long link's title")
+
+ [This long line is comprised entirely of a link](http://example.com "But is inside a code block") {MD013}
+
+This [long line is comprised mostly of a link](http://example.com "This is the long link's title") {MD013}
+
+[This long line is comprised mostly of a link](http://example.com "This is the long link's title") text {MD013}
+
+This long line includes a simple [reference][label] link and is long enough to violate the rule. {MD013}
+
+[This long line is comprised entirely of a reference link and is long enough to violate the rule][label]
+
+[label]: http://example.org "Title for a link reference that is itself long enough to violate the rule"
+
+[Link to broken label][notlabel]
+
+[notlabel\]: notlink "Invalid syntax for a link label because the right bracket is backslash-escaped {MD013}"
diff --git a/test/markdownlint-test.js b/test/markdownlint-test.js
index 2b00e173..1e61314a 100644
--- a/test/markdownlint-test.js
+++ b/test/markdownlint-test.js
@@ -905,7 +905,7 @@ module.exports.missingStringValue = function missingStringValue(test) {
};
module.exports.ruleNamesUpperCase = function ruleNamesUpperCase(test) {
- test.expect(39);
+ test.expect(40);
rules.forEach(function forRule(rule) {
test.equal(rule.name, rule.name.toUpperCase(), "Rule name not upper-case.");
});
@@ -913,7 +913,7 @@ module.exports.ruleNamesUpperCase = function ruleNamesUpperCase(test) {
};
module.exports.uniqueAliases = function uniqueAliases(test) {
- test.expect(78);
+ test.expect(80);
var tags = [];
rules.forEach(function forRule(rule) {
Array.prototype.push.apply(tags, rule.tags);
@@ -930,7 +930,7 @@ module.exports.uniqueAliases = function uniqueAliases(test) {
};
module.exports.readme = function readme(test) {
- test.expect(101);
+ test.expect(104);
var tagToRules = {};
rules.forEach(function forRule(rule) {
rule.tags.forEach(function forTag(tag) {
@@ -991,7 +991,7 @@ module.exports.readme = function readme(test) {
};
module.exports.doc = function doc(test) {
- test.expect(295);
+ test.expect(303);
fs.readFile("doc/Rules.md", shared.utf8Encoding,
function readFile(err, contents) {
test.ifError(err);
diff --git a/test/md041-ignore-leading-comments-combined.json b/test/md041-ignore-leading-comments-combined.json
new file mode 100644
index 00000000..2be9298b
--- /dev/null
+++ b/test/md041-ignore-leading-comments-combined.json
@@ -0,0 +1,4 @@
+{
+ "default": true,
+ "first-line-h1": true
+}
diff --git a/test/md041-ignore-leading-comments-combined.md b/test/md041-ignore-leading-comments-combined.md
new file mode 100644
index 00000000..e3dc0814
--- /dev/null
+++ b/test/md041-ignore-leading-comments-combined.md
@@ -0,0 +1,11 @@
+# Heading #
+
+Text text text
+
+Embedded tab
+
+Text text text
+
+Trailing space {MD009}
+
+Text text text
diff --git a/test/md041-ignore-leading-comments-violation.json b/test/md041-ignore-leading-comments-violation.json
new file mode 100644
index 00000000..2be9298b
--- /dev/null
+++ b/test/md041-ignore-leading-comments-violation.json
@@ -0,0 +1,4 @@
+{
+ "default": true,
+ "first-line-h1": true
+}
diff --git a/test/md041-ignore-leading-comments-violation.md b/test/md041-ignore-leading-comments-violation.md
new file mode 100644
index 00000000..58ca7025
--- /dev/null
+++ b/test/md041-ignore-leading-comments-violation.md
@@ -0,0 +1,11 @@
+
+
+Text text text {MD041}
+
+Embedded tab
+
+Text text text
+
+Trailing space {MD009}
+
+Text text text
diff --git a/test/md041-ignore-leading-comments.json b/test/md041-ignore-leading-comments.json
new file mode 100644
index 00000000..2be9298b
--- /dev/null
+++ b/test/md041-ignore-leading-comments.json
@@ -0,0 +1,4 @@
+{
+ "default": true,
+ "first-line-h1": true
+}
diff --git a/test/md041-ignore-leading-comments.md b/test/md041-ignore-leading-comments.md
new file mode 100644
index 00000000..3c61047d
--- /dev/null
+++ b/test/md041-ignore-leading-comments.md
@@ -0,0 +1,13 @@
+
+
+# Heading
+
+Text text text
+
+Embedded tab
+
+Text text text
+
+Trailing space {MD009}
+
+Text text text
diff --git a/test/proper-names.json b/test/proper-names.json
new file mode 100644
index 00000000..1d8c37b7
--- /dev/null
+++ b/test/proper-names.json
@@ -0,0 +1,13 @@
+{
+ "default": true,
+ "MD044": {
+ "names": [
+ "markdownlint",
+ "JavaScript",
+ "Node.js",
+ "GitHub",
+ "npm",
+ "Internet Explorer"
+ ]
+ }
+}
diff --git a/test/proper-names.md b/test/proper-names.md
new file mode 100644
index 00000000..675197cb
--- /dev/null
+++ b/test/proper-names.md
@@ -0,0 +1,45 @@
+# markdownlint test file
+
+Markdownlint is a tool {MD044}
+
+JavaScript is a language
+
+JavaScript is not Java
+
+Nor is it Javascript. {MD044}
+
+markdownlint runs on Node.js via npm
+
+Node is an environment
+
+Install into it with NPM {MD044}
+
+Node.JSX is not a real thing
+
+Nor is nodesjs or NPMI
+
+npm can npm stand npm for npm many npm things
+
+Writing npm is right, but NPM is wrong {MD044}
+
+Get excited about Github! {MD044}
+
+Share code on GitHub via Git
+
+Internet Explorer is a web browser
+
+OTOH, "internet explorer" is a job {MD044}
+
+## node.js instructions {MD044}
+
+Code in `javascript` {MD044}
+
+Execute `via the node.js engine` {MD044}
+
+* Use NPM {MD044}
+
+> Run Markdownlint on your README {MD044}
+
+Upload the code (to github) {MD044}
+
+Link to [github](https://github.com/). {MD044}
diff --git a/test/spaces_inside_codespan_elements.md b/test/spaces_inside_codespan_elements.md
index f0e08952..5c60b40f 100644
--- a/test/spaces_inside_codespan_elements.md
+++ b/test/spaces_inside_codespan_elements.md
@@ -6,6 +6,10 @@
` codespan element with spaces inside ` {MD038}
+empty `` codespan element
+
+single space ` ` codespan element {MD038}
+
`,`, `.`
`,`, `code`
@@ -21,3 +25,33 @@ text `code` text `anything` code `end`
text `anything` code `code` text `end`
text `anything` text `anything` code `anything` `code`
+
+text ``code`` text ``code`` text
+
+text `` code`` text {MD038}
+
+text ``code `` text {MD038}
+
+text ```code``` text ```code``` text
+
+text ```code``` text `` code`` text {MD038}
+
+text ```code``` text ``code `` text {MD038}
+
+``embedded ` backtick`` text `code`
+
+`backslash does not escape \` backtick`
+
+`` ` `` text `code`
+
+` `` ` text `code`
+
+``` ` leading space allowed for backtick``` text `code`
+
+``` ` multiple leading spaces not allowed``` text `code` {MD038}
+
+``trailing space allowed for backtick ` `` text `code`
+
+``multiple trailing spaces not allowed ` `` text `code` {MD038}
+
+`` ` leading and trailing space allowed for backtick ` `` text `code`