mdl 0.3.1 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 936be64bf79d5bead9ce46cc5f259a4e7d011084
4
- data.tar.gz: b31fb00915f2b8b3a400758a6d08c273138523eb
3
+ metadata.gz: e51fd852e7791bcde9513e139c43c93fc0377ec3
4
+ data.tar.gz: d566428c48d875eb1bd0f89e4cdff094f50a23d6
5
5
  SHA512:
6
- metadata.gz: e29b0812ef5eff2cebe992da2dcb9887197d59756ccfc2443adeadfb67ec2a3d7a03d3c129f794f804808705208d26271af0414ebfbe631d028c346c43cda806
7
- data.tar.gz: edf20cb26c6d61cb735b264e9798ab9abe6347374efcef73221408d2d97b44980530e90a4fcd9fba0c309cdefbcc77c08344147b4a0fb48cfc44bbc1ab30927f
6
+ metadata.gz: dd7a9864461857232915798e54111bfeaf3cc957b53fed0dc74bc28e94496e13616f91be2e2b930f38fcbb1581108f8e41e4dd5e642eb6f2cd411becb31376a8
7
+ data.tar.gz: d561fd970ab869fb6a43780e19b20d861e4f46a48e891bfc9e5e99c464afcfc0295715e22f2c2986ca0b70f91c7b0b3b41b660519586d5ffa3eed705f63f9527
@@ -1,7 +1,9 @@
1
1
  language: ruby
2
- rvm:
3
- - "1.9.2"
4
- - "2.1.0"
5
- - "2.1.6"
6
- - "2.3.0"
7
- - jruby-19mode # JRuby in 1.9 mode
2
+
3
+ matrix:
4
+ include:
5
+ - rvm: 2.1.10
6
+ - rvm: 2.2.5
7
+ - rvm: 2.3.1
8
+ - rvm: jruby-9.1.2.0
9
+ env: JRUBY_OPTS="--dev"
@@ -1,28 +1,36 @@
1
1
  # Change Log
2
2
 
3
- ## [v0.3.1](https://github.com/mivok/markdownlint/tree/v0.3.1) (2016-03-20)
3
+ ## [v0.4.0] (2016-08-22)
4
4
 
5
- [Full Changelog](https://github.com/mivok/markdownlint/compare/v0.3.0...v0.3.1)
5
+ ### Added
6
6
 
7
- ### Bugs fixed
7
+ * Ignore yaml front matter option (#130, #143)
8
8
 
9
- * Fix error on starting mdl
9
+ ### Changed
10
+
11
+ * Allow top level header rules (MD002, MD025, MD041) to be configurable (#142)
10
12
 
11
- ## [v0.3.0](https://github.com/mivok/markdownlint/tree/v0.3.0) (2016-03-19)
13
+ ### Fixed
12
14
 
13
- [Full Changelog](https://github.com/mivok/markdownlint/compare/v0.2.1...v0.3.0)
15
+ * Read UTF-8 files correctly even if locale is set to C (#135, #146, #147,
16
+ #148)
17
+ * Fix issues loading .mdlrc file (#126, #129, #133, #148)
18
+ * Fix erroneous triggering of MD022/MD023 in some cases (#144)
19
+ * Detect codeblock lines correctly when ignoring them (#141)
14
20
 
15
- ### Rules added/changed
21
+ ## [v0.3.1] (2016-03-20)
22
+
23
+ ### Fixed
24
+
25
+ * Fix error on starting mdl
26
+
27
+ ## [v0.3.0] (2016-03-19)
28
+
29
+ ### Rules added
16
30
 
17
31
  * MD041 - First line in file should be a top level header
18
- * MD003 - An additional header style, setext_with_atx, was added to require
19
- setext style headers for levels 1 and 2, but allow atx style headers for
20
- levels 3 and above (i.e. header levels that can't be expressed with setext
21
- style headers)
22
- * MD013 - You now have the option to exclude code blocks and tables from the
23
- line length limit check.
24
32
 
25
- ### Enhancements implemented
33
+ ### Added
26
34
 
27
35
  * You can now load your own custom rules with the `-u` option. See
28
36
  [rules.rb](https://github.com/mivok/markdownlint/blob/master/lib/mdl/rules.rb)
@@ -33,7 +41,16 @@
33
41
  You can pass the `-a` option to display rule aliases instead of MDxxx rule
34
42
  IDs.
35
43
 
36
- ### Bugs fixed
44
+ ### Changed
45
+
46
+ * MD003 - An additional header style, setext_with_atx, was added to require
47
+ setext style headers for levels 1 and 2, but allow atx style headers for
48
+ levels 3 and above (i.e. header levels that can't be expressed with setext
49
+ style headers)
50
+ * MD013 - You now have the option to exclude code blocks and tables from the
51
+ line length limit check.
52
+
53
+ ### Fixed
37
54
 
38
55
  * Crash with MD034 and pipe character (#93, #97)
39
56
  * MD031 failed on nested code blocks (#100, #109)
@@ -53,11 +70,9 @@
53
70
  * [MD013: allow excluding code blocks and tables - Loic
54
71
  Nageleisen](https://github.com/mivok/markdownlint/pull/112)
55
72
 
56
- ## [v0.2.1](https://github.com/mivok/markdownlint/tree/v0.2.1) (2015-04-13)
57
-
58
- [Full Changelog](https://github.com/mivok/markdownlint/compare/v0.2.0...v0.2.1)
73
+ ## [v0.2.1] (2015-04-13)
59
74
 
60
- ### Bugs fixed
75
+ ### Fixed
61
76
 
62
77
  * Incorrect parsing of rules/tags specification in .mdlrc (#81)
63
78
  * Exception on image links with MD039 (#82)
@@ -67,9 +82,7 @@
67
82
 
68
83
  * Exception on some lines with raw html list items in them (#83)
69
84
 
70
- ## [v0.2.0](https://github.com/mivok/markdownlint/tree/v0.2.0) (2015-04-13)
71
-
72
- [Full Changelog](https://github.com/mivok/markdownlint/compare/v0.1.0...v0.2.0)
85
+ ## [v0.2.0] (2015-04-13)
73
86
 
74
87
  ### Rules added
75
88
 
@@ -82,7 +95,7 @@
82
95
  * MD039 - Spaces inside link text
83
96
  * MD040 - Fenced code blocks should have a language specified
84
97
 
85
- ## Enhancements implemented
98
+ ## Added
86
99
 
87
100
  * Trailing spaces rule should allow an excemption for deliberate <br/\>
88
101
  insertion.
@@ -93,16 +106,14 @@
93
106
 
94
107
  * [Add parameter (value and default) information to rule documentation. - David Anson](https://github.com/mivok/markdownlint/pull/76)
95
108
 
96
- ## [v0.1.0](https://github.com/mivok/markdownlint/tree/v0.1.0) (2015-02-22)
97
-
98
- [Full Changelog](https://github.com/mivok/markdownlint/compare/v0.0.1...v0.1.0)
109
+ ## [v0.1.0] (2015-02-22)
99
110
 
100
111
  ### Rules added
101
112
 
102
113
  * MD031 - Fenced code blocks should be surrounded by blank lines
103
114
  * MD032 - Lists should be surrounded by blank lines
104
115
 
105
- ### Bugs fixed
116
+ ### Fixed
106
117
 
107
118
  * MD014 triggers when it shouldn't
108
119
 
@@ -113,7 +124,7 @@
113
124
  * [Clarify how to specify your own style - mjankowski](https://github.com/mivok/markdownlint/pull/65)
114
125
  * [Use single quotes to prevent early escaping - highb](https://github.com/mivok/markdownlint/pull/64)
115
126
 
116
- ## [v0.0.1](https://github.com/mivok/markdownlint/tree/v0.0.1) (2014-09-07)
127
+ ## [v0.0.1] (2014-09-07)
117
128
 
118
129
  ### Rules added
119
130
 
@@ -143,3 +154,12 @@
143
154
  * MD028 - Blank line inside blockquote
144
155
  * MD029 - Ordered list item prefix
145
156
  * MD030 - Spaces after list markers
157
+
158
+ [Unreleased]: https://github.com/mivok/markdownlint/tree/master
159
+ [v0.4.0]: https://github.com/mivok/markdownlint/tree/v0.4.0
160
+ [v0.3.1]: https://github.com/mivok/markdownlint/tree/v0.3.1
161
+ [v0.3.0]: https://github.com/mivok/markdownlint/tree/v0.3.0
162
+ [v0.2.1]: https://github.com/mivok/markdownlint/tree/v0.2.1
163
+ [v0.2.0]: https://github.com/mivok/markdownlint/tree/v0.2.0
164
+ [v0.1.0]: https://github.com/mivok/markdownlint/tree/v0.1.0
165
+ [v0.0.1]: https://github.com/mivok/markdownlint/tree/v0.0.1
data/README.md CHANGED
@@ -10,7 +10,7 @@ A tool to check markdown files and flag style issues.
10
10
 
11
11
  Markdownlint is written in ruby and is distributed as a rubygem. As long as
12
12
  you have a relatively up to date ruby on your system, markdownlint will be
13
- simple to install and use.
13
+ simple to install and use. You have 2 options to install it:
14
14
 
15
15
  To install from rubygems, run:
16
16
 
@@ -22,6 +22,11 @@ To install the latest development version from github:
22
22
  cd markdownlint
23
23
  rake install
24
24
 
25
+
26
+ Note that you will need [rake](https://github.com/ruby/rake)
27
+ (`gem install rake`) and [bundler](https://github.com/bundler/bundler)
28
+ (`gem install bundler`) in order to build from source.
29
+
25
30
  ## Usage
26
31
 
27
32
  To have markdownlint check your markdown files, simply run `mdl` with the
@@ -74,7 +79,7 @@ For more information on creating style files, see the
74
79
 
75
80
  ## Contributing
76
81
 
77
- 1. Fork it ( http://github.com/mivok/markdownlint/fork )
82
+ 1. Fork it ( <http://github.com/mivok/markdownlint/fork> )
78
83
  1. Create your feature branch (`git checkout -b my-new-feature`)
79
84
  1. Commit your changes (`git commit -am 'Add some feature'`)
80
85
  1. Push to the branch (`git push origin my-new-feature`)
@@ -35,12 +35,14 @@ level at a time:
35
35
  ### Another Header 3
36
36
 
37
37
 
38
- ## MD002 - First header should be a h1 header
38
+ ## MD002 - First header should be a top level header
39
39
 
40
40
  Tags: headers
41
41
 
42
42
  Aliases: first-header-h1
43
43
 
44
+ Parameters: level (number; default 1)
45
+
44
46
  This rule is triggered when the first header in the document isn't a h1 header:
45
47
 
46
48
  ## This isn't a H1 header
@@ -506,6 +508,8 @@ Tags: headers
506
508
 
507
509
  Aliases: single-h1
508
510
 
511
+ Parameters: level (number; default 1)
512
+
509
513
  This rule is triggered when a top level header is in use (the first line of
510
514
  the file is a h1 header), and more than one h1 header is in use in the
511
515
  document:
@@ -529,6 +533,9 @@ serves as the title for the document. If this convention is in use, then there
529
533
  can not be more than one title for the document, and the entire document
530
534
  should be contained within this header.
531
535
 
536
+ Note: The `level` parameter can be used to change the top level (ex: to h2) in
537
+ cases where an h1 is added externally.
538
+
532
539
  ## MD026 - Trailing punctuation in header
533
540
 
534
541
  Tags: headers
@@ -968,6 +975,8 @@ Tags: headers
968
975
 
969
976
  Aliases: first-line-h1
970
977
 
978
+ Parameters: level (number; default 1)
979
+
971
980
  This rule is triggered when the first line in the file isn't a top level (h1)
972
981
  header:
973
982
 
@@ -982,3 +991,6 @@ To fix this, add a header to the top of your file:
982
991
 
983
992
  This is a file with a top level header
984
993
  ```
994
+
995
+ Note: The `level` parameter can be used to change the top level (ex: to h2) in
996
+ cases where an h1 is added externally.
@@ -39,6 +39,16 @@ instead, and ignore any files git doesn't know about.
39
39
  * Config file: `git_recurse true`
40
40
  * Default: false
41
41
 
42
+ Ignore YAML front matter - if this option is enabled markdownlint will ignore
43
+ content within valid
44
+ [YAML front matter](https://jekyllrb.com/docs/frontmatter/). Reported line
45
+ numbers will still match the file contents but markdownlint will consider the
46
+ line following front matter to be the first line.
47
+
48
+ * Command line: `-i`, `--ignore-front-matter`
49
+ * Config file: `ignore-front-matter true`
50
+ * Default: false
51
+
42
52
  ### Specifying which rules mdl processes
43
53
 
44
54
  Tags - Limit the rules mdl enables to those containing the provided tags.
@@ -14,28 +14,36 @@ branch.
14
14
 
15
15
  Update the changelog:
16
16
 
17
- * Add a new header and 'full changelog' link for the new release:
17
+ * Add a new header and link for the new release, replacing any 'Unreleased'
18
+ header.
18
19
 
19
- ## [v0.2.0](https://github.com/mivok/markdownlint/tree/v0.2.0) (2015-04-13)
20
+ ## [v0.2.0] (2015-04-13)
20
21
 
21
- [Full Changelog](https://github.com/mivok/markdownlint/compare/v0.1.0...v0.2.0)
22
+ This goes at the bottom:
22
23
 
23
- * Add an 'Rules added' section, listing every new rule added for this version.
24
+ [v0.2.0]: https://github.com/mivok/markdownlint/tree/v0.2.0
25
+
26
+ * Changelog entries can and should be added in an 'Unreleased' section as
27
+ commits are made. However, the following steps can be performed before each
28
+ release to catch anything that was missed.
29
+ * Add a 'Rules added' section, listing every new rule added for this version.
24
30
  * Use `git diff v0.1.0..v0.2.0 docs/RULES.md | grep '## MD'` to discover
25
31
  what these are.
26
32
  * Search for closed issues:
27
33
  * Go to <https://github.com/mivok/markdownlint/issues>
28
- * Search for `is:closed closed:>1900-01-01`, changing the date to the date
34
+ * Search for `closed:>1900-01-01`, changing the date to the date
29
35
  of the last release.
30
36
  * From this list of issues, make sections for:
31
- * Enhancements implemented
32
- * Bugs fixed
33
- * Search for merged pull requests:
34
- * Search for `is:pull-request merged:>1900-01-01`
35
- * Add an entry for each merged pull request:
36
- * `[Title - author](https://github.com/mivok/markdownlint/pull/NN)`
37
+ * Added - for new features
38
+ * Changed - for changes in existing functionality
39
+ * Deprecated - for once-stable features removed in upcoming releases
40
+ * Removed - for deprecated features removed in this release
41
+ * Fixed - for any bug fixes
42
+ * Security - for any security issues
37
43
 
38
44
  Next, run `rake release`. This will:
39
45
 
40
46
  * Tag vX.Y.Z in git and push it.
41
47
  * Upload the new gem to rubygems.org
48
+
49
+ Finally, add a new 'Unreleased' section to the changelog for the next release.
data/lib/mdl.rb CHANGED
@@ -71,7 +71,7 @@ module MarkdownLint
71
71
  status = 0
72
72
  cli.cli_arguments.each do |filename|
73
73
  puts "Checking #{filename}..." if Config[:verbose]
74
- doc = Doc.new_from_file(filename)
74
+ doc = Doc.new_from_file(filename, Config[:ignore_front_matter])
75
75
  filename = '(stdin)' if filename == "-"
76
76
  if Config[:show_kramdown_warnings]
77
77
  status = 2 if not doc.parsed.warnings.empty?
@@ -85,6 +85,7 @@ module MarkdownLint
85
85
  next if error_lines.nil? or error_lines.empty?
86
86
  status = 1
87
87
  error_lines.each do |line|
88
+ line += doc.offset # Correct line numbers for any yaml front matter
88
89
  if Config[:show_aliases]
89
90
  puts "#{filename}:#{line}: #{rule.aliases.first || id} #{rule.description}"
90
91
  else
@@ -27,6 +27,12 @@ module MarkdownLint
27
27
  :description => 'Increase verbosity',
28
28
  :boolean => true
29
29
 
30
+ option :ignore_front_matter,
31
+ :short => '-i',
32
+ :long => '--[no-]ignore-front-matter',
33
+ :boolean => true,
34
+ :description => 'Ignore YAML front matter'
35
+
30
36
  option :show_kramdown_warnings,
31
37
  :short => '-w',
32
38
  :long => '--[no-]warnings',
@@ -97,13 +103,14 @@ module MarkdownLint
97
103
 
98
104
  # Load the config file if it's present
99
105
  filename = CLI.probe_config_file(config[:config_file])
106
+
100
107
  # Only fall back to ~/.mdlrc if we are using the default value for -c
101
108
  if filename.nil? and config[:config_file] == CONFIG_FILE
102
109
  filename = File.expand_path("~/#{CONFIG_FILE}")
103
110
  end
104
111
 
105
112
  if not filename.nil? and File.exist?(filename)
106
- MarkdownLint::Config.from_file(filename)
113
+ MarkdownLint::Config.from_file(filename.to_s)
107
114
  if config[:verbose]
108
115
  puts "Loaded config from #{filename}"
109
116
  end
@@ -147,15 +154,15 @@ module MarkdownLint
147
154
  end
148
155
 
149
156
  def self.probe_config_file(path)
150
- # Probe up only for plain filenames
151
- if path != File.basename(path)
152
- return File.expand_path(path)
153
- end
157
+ expanded_path = File.expand_path(path)
158
+ return expanded_path if File.exist?(expanded_path)
154
159
 
155
160
  # Look for a file up from the working dir
156
- Pathname.new(path).ascend do |p|
161
+ Pathname.new(expanded_path).ascend do |p|
162
+ next unless p.directory?
163
+
157
164
  config_file = p.join(CONFIG_FILE)
158
- return config_file if File.exist?(CONFIG_FILE)
165
+ return config_file if File.exist?(config_file)
159
166
  end
160
167
  nil
161
168
  end
@@ -24,10 +24,23 @@ module MarkdownLint
24
24
 
25
25
  attr_reader :elements
26
26
 
27
+ ##
28
+ # The line number offset which is greater than zero when the
29
+ # markdown file contains YAML front matter that should be ignored.
30
+
31
+ attr_reader :offset
32
+
27
33
  ##
28
34
  # Create a new document given a string containing the markdown source
29
35
 
30
- def initialize(text)
36
+ def initialize(text, ignore_front_matter = false)
37
+ regex = /^---\n(.*?)---\n/m
38
+ if ignore_front_matter and regex.match(text)
39
+ @offset = regex.match(text).to_s.split("\n").length
40
+ text.sub!(regex,'')
41
+ else
42
+ @offset = 0
43
+ end
31
44
  @lines = text.split("\n")
32
45
  @parsed = Kramdown::Document.new(text, :input => 'MarkdownLint')
33
46
  @elements = @parsed.root.children
@@ -37,11 +50,11 @@ module MarkdownLint
37
50
  ##
38
51
  # Alternate 'constructor' passing in a filename
39
52
 
40
- def self.new_from_file(filename)
53
+ def self.new_from_file(filename, ignore_front_matter = false)
41
54
  if filename == "-"
42
- self.new(STDIN.read)
55
+ self.new(STDIN.read, ignore_front_matter)
43
56
  else
44
- self.new(File.read(filename))
57
+ self.new(File.read(filename, encoding: 'UTF-8'), ignore_front_matter)
45
58
  end
46
59
  end
47
60
 
@@ -15,12 +15,13 @@ rule "MD001", "Header levels should only increment by one level at a time" do
15
15
  end
16
16
  end
17
17
 
18
- rule "MD002", "First header should be a h1 header" do
18
+ rule "MD002", "First header should be a top level header" do
19
19
  tags :headers
20
20
  aliases 'first-header-h1'
21
+ params :level => 1
21
22
  check do |doc|
22
23
  first_header = doc.find_type(:header).first
23
- [first_header[:location]] if first_header and first_header[:level] != 1
24
+ [first_header[:location]] if first_header and first_header[:level] != @params[:level]
24
25
  end
25
26
  end
26
27
 
@@ -164,7 +165,7 @@ rule "MD012", "Multiple consecutive blank lines" do
164
165
  # inside of a code block are acceptable.
165
166
  codeblock_lines = doc.find_type_elements(:codeblock).map{
166
167
  |e| (doc.element_linenumber(e)..
167
- doc.element_linenumber(e) + e.value.count('\n') - 1).to_a }.flatten
168
+ doc.element_linenumber(e) + e.value.lines.count).to_a }.flatten
168
169
  blank_lines = doc.matching_lines(/^\s*$/)
169
170
  cons_blank_lines = blank_lines.each_cons(2).select{
170
171
  |p, n| n - p == 1}.map{|p, n| n}
@@ -180,7 +181,7 @@ rule "MD013", "Line length" do
180
181
  # Every line in the document that is part of a code block.
181
182
  codeblock_lines = doc.find_type_elements(:codeblock).map{
182
183
  |e| (doc.element_linenumber(e)..
183
- doc.element_linenumber(e) + e.value.count('\n') - 1).to_a }.flatten
184
+ doc.element_linenumber(e) + e.value.lines.count).to_a }.flatten
184
185
  # Every line in the document that is part of a table.
185
186
  locations = doc.elements
186
187
  .map { |e| [e.options[:location], e] }
@@ -272,7 +273,7 @@ rule "MD022", "Headers should be surrounded by blank lines" do
272
273
  # Kramdown requires that headers start on a block boundary, so in most
273
274
  # cases it won't pick up a header without a blank line before it. We need
274
275
  # to check regular text and pick out headers ourselves too
275
- doc.find_type_elements(:p).each do |p|
276
+ doc.find_type_elements(:p, false).each do |p|
276
277
  linenum = doc.element_linenumber(p)
277
278
  text = p.children.select { |e| e.type == :text }.map {|e| e.value }.join
278
279
  lines = text.split("\n")
@@ -307,7 +308,7 @@ rule "MD023", "Headers must start at the beginning of the line" do
307
308
  end
308
309
  # Next we have to look for things that aren't parsed as headers because
309
310
  # they start with spaces.
310
- doc.find_type_elements(:p).each do |p|
311
+ doc.find_type_elements(:p, false).each do |p|
311
312
  linenum = doc.element_linenumber(p)
312
313
  lines = doc.extract_text(p)
313
314
  prev_line = ""
@@ -342,8 +343,9 @@ end
342
343
  rule "MD025", "Multiple top level headers in the same document" do
343
344
  tags :headers
344
345
  aliases 'single-h1'
346
+ params :level => 1
345
347
  check do |doc|
346
- headers = doc.find_type(:header).select { |h| h[:level] == 1 }
348
+ headers = doc.find_type(:header).select { |h| h[:level] == params[:level] }
347
349
  if not headers.empty? and doc.element_linenumber(headers[0]) == 1
348
350
  headers[1..-1].map { |h| doc.element_linenumber(h) }
349
351
  end
@@ -599,9 +601,10 @@ end
599
601
  rule "MD041", "First line in file should be a top level header" do
600
602
  tags :headers
601
603
  aliases 'first-line-h1'
604
+ params :level => 1
602
605
  check do |doc|
603
606
  first_header = doc.find_type(:header).first
604
607
  [1] if first_header.nil? or first_header[:location] != 1 \
605
- or first_header[:level] != 1
608
+ or first_header[:level] != params[:level]
606
609
  end
607
610
  end
@@ -1,3 +1,3 @@
1
1
  module MarkdownLint
2
- VERSION = "0.3.1"
2
+ VERSION = "0.4.0"
3
3
  end
@@ -20,12 +20,12 @@ Gem::Specification.new do |spec|
20
20
 
21
21
  spec.required_ruby_version = '>= 1.9.2'
22
22
 
23
- spec.add_dependency 'kramdown', '~> 1.8', '>= 1.8.0'
24
- spec.add_dependency 'mixlib-config', '~> 2.1', '>= 2.1.0'
25
- spec.add_dependency 'mixlib-cli', '~> 1.5', '>= 1.5.0'
23
+ spec.add_dependency 'kramdown', '~> 1.12', '>= 1.12.0'
24
+ spec.add_dependency 'mixlib-config', '~> 2.2', '>= 2.2.1'
25
+ spec.add_dependency 'mixlib-cli', '~> 1.7', '>= 1.7.0'
26
26
 
27
- spec.add_development_dependency 'bundler', '~> 1.5'
28
- spec.add_development_dependency 'rake', '~> 10.0'
29
- spec.add_development_dependency 'minitest', '~> 5.0'
27
+ spec.add_development_dependency 'bundler', '~> 1.12'
28
+ spec.add_development_dependency 'rake', '~> 11.2'
29
+ spec.add_development_dependency 'minitest', '~> 5.9'
30
30
  spec.add_development_dependency 'pry', '~> 0.10'
31
31
  end
@@ -0,0 +1,16 @@
1
+ ---
2
+ layout: post
3
+ title: Hello World!
4
+ category: Meta
5
+ tags:
6
+ - tag
7
+ - another tag
8
+ - one more tag
9
+ url: http://example.com
10
+ excerpt: Hello World! Vestibulum imperdiet adipiscing arcu, quis aliquam dolor condimentum dapibus. Aliquam fermentum leo aliquet quam volutpat et molestie mauris mattis. Suspendisse semper consequat velit in suscipit.
11
+ ---
12
+ # header1
13
+
14
+ This is just a sample post.
15
+
16
+ ### offending header3
@@ -0,0 +1,3 @@
1
+ ## A level 2 top level header
2
+
3
+ ## Another one {MD025}
@@ -0,0 +1,4 @@
1
+ all
2
+ rule 'MD002', :level => 2
3
+ rule 'MD025', :level => 2
4
+ rule 'MD041', :level => 2
@@ -6,4 +6,7 @@ Some text
6
6
  Some text
7
7
  ## Header 4 {MD022}
8
8
 
9
- ## Header 5
9
+ ## Header 5
10
+
11
+ * This shouldn't trigger MD022, but did because of some bug where we tried to
12
+ #catch headers that kramdown didn't parse correctly.
@@ -6,4 +6,15 @@ Some text
6
6
  ===================================
7
7
 
8
8
  Setext style title only indented {MD023}
9
- =========================================
9
+ =========================================
10
+
11
+ * Test situations in which MD023 shouldn't be triggered.
12
+
13
+ ```rb
14
+ # This shouldn't trigger MD023 as it is a code comment.
15
+ foo = "And here is some code"
16
+ ```
17
+
18
+ * This is another case where MD023 shouldn't be triggered
19
+ # Test
20
+ # Test
@@ -9,6 +9,13 @@ Here is a short line in a code block.
9
9
  Here is a very very very very very very very very very very very very very very very very very very very long line in a code block.
10
10
  ```
11
11
 
12
+ ```text
13
+ test
14
+ test
15
+
16
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut
17
+ ```
18
+
12
19
  This is a short line.
13
20
 
14
21
  | First Header | Second Header | Third Header | Fourth Header | Fifth Header | Sixth Header |
@@ -1,51 +1,9 @@
1
1
  require_relative 'setup_tests'
2
2
  require 'open3'
3
3
  require 'set'
4
+ require 'fileutils'
4
5
 
5
6
  class TestCli < Minitest::Test
6
- def run_cli(args, stdin = "", mdlrc="default_mdlrc")
7
- mdl_script = File.expand_path("../../bin/mdl", __FILE__)
8
- # Load the mdlrc file from the text/fixtures/ directory
9
- mdlrc = File.expand_path("../fixtures/#{mdlrc}", __FILE__)
10
- result = {}
11
- result[:stdout], result[:stderr], result[:status] = \
12
- Open3.capture3(*(%W{bundle exec #{mdl_script} -c #{mdlrc}} + args.split),
13
- :stdin_data => stdin)
14
- result[:status] = result[:status].exitstatus
15
- result
16
- end
17
-
18
- def assert_rules_enabled(result, rules, only_these_rules=false)
19
- # Asserts that the given rules are enabled given the output of mdl -l
20
- # If only_these_rules is set, then it asserts that the given rules and no
21
- # others are enabled.
22
- lines = result[:stdout].split("\n")
23
- assert_equal("Enabled rules:", lines.first)
24
- lines.shift
25
- rules = rules.to_set
26
- enabled_rules = lines.map{ |l| l.split(" ").first }.to_set
27
- if only_these_rules
28
- assert_equal(rules, enabled_rules)
29
- else
30
- assert_equal(Set.new, rules - enabled_rules)
31
- end
32
- end
33
-
34
- def assert_rules_disabled(result, rules)
35
- # Asserts that the given rules are _not_ enabled given the output of mdl -l
36
- lines = result[:stdout].split("\n")
37
- assert_equal("Enabled rules:", lines.first)
38
- lines.shift
39
- rules = rules.to_set
40
- enabled_rules = lines.map{ |l| l.split(" ").first }.to_set
41
- assert_equal(Set.new, rules & enabled_rules)
42
- end
43
-
44
- def assert_ran_ok(result)
45
- assert_equal(0, result[:status])
46
- assert_equal("", result[:stderr])
47
- end
48
-
49
7
  def test_help_text
50
8
  result = run_cli("--help")
51
9
  assert_match(/Usage: \S+ \[options\]/, result[:stdout])
@@ -65,12 +23,20 @@ class TestCli < Minitest::Test
65
23
  end
66
24
 
67
25
  def test_show_alias_processing_file
68
- result = run_cli("-a -r MD002", "## header2")
26
+ result = run_cli_with_input("-a -r MD002", "## header2")
69
27
  assert_equal(1, result[:status])
70
28
  assert_equal("", result[:stderr])
71
29
  assert_match(/^\(stdin\):1: first-header-h1/, result[:stdout])
72
30
  end
73
31
 
32
+ def test_running_on_unicode_input
33
+ result = run_cli_with_file_and_ascii_env("## header2 🚀")
34
+ assert_equal(1, result[:status])
35
+ assert_equal("", result[:stderr])
36
+ assert_match(/MD002 First header should be a top level header/,
37
+ result[:stdout])
38
+ end
39
+
74
40
  def test_skipping_default_ruleset_loading
75
41
  result = run_cli("-ld")
76
42
  assert_rules_enabled(result, [], true)
@@ -94,14 +60,14 @@ class TestCli < Minitest::Test
94
60
 
95
61
  def test_custom_ruleset_processing_success
96
62
  my_ruleset = File.expand_path("../fixtures/my_ruleset.rb", __FILE__)
97
- result = run_cli("-du #{my_ruleset}", "Hello World")
63
+ result = run_cli_with_input("-du #{my_ruleset}", "Hello World")
98
64
  assert_equal("", result[:stdout])
99
65
  assert_ran_ok(result)
100
66
  end
101
67
 
102
68
  def test_custom_ruleset_processing_failure
103
69
  my_ruleset = File.expand_path("../fixtures/my_ruleset.rb", __FILE__)
104
- result = run_cli("-du #{my_ruleset}", "Goodbye world")
70
+ result = run_cli_with_input("-du #{my_ruleset}", "Goodbye world")
105
71
  assert_equal(1, result[:status])
106
72
  assert_match(/^\(stdin\):1: MY001/, result[:stdout])
107
73
  assert_equal("", result[:stderr])
@@ -111,7 +77,7 @@ class TestCli < Minitest::Test
111
77
  # The custom rule doesn't have an alias, so the output should be identical
112
78
  # to that without show_alias enabled.
113
79
  my_ruleset = File.expand_path("../fixtures/my_ruleset.rb", __FILE__)
114
- result = run_cli("-dau #{my_ruleset}", "Goodbye world")
80
+ result = run_cli_with_input("-dau #{my_ruleset}", "Goodbye world")
115
81
  assert_equal(1, result[:status])
116
82
  assert_match(/^\(stdin\):1: MY001/, result[:stdout])
117
83
  assert_equal("", result[:stderr])
@@ -157,27 +123,45 @@ class TestCli < Minitest::Test
157
123
  end
158
124
 
159
125
  def test_rule_inclusion_config
160
- result = run_cli("-l", "", "mdlrc_enable_rules")
126
+ result = run_cli_with_custom_rc_file("-l", "mdlrc_enable_rules")
161
127
  assert_ran_ok(result)
162
128
  assert_rules_enabled(result, ["MD001", "MD002"], true)
163
129
  end
164
130
 
165
131
  def test_rule_exclusion_config
166
- result = run_cli("-l", "", "mdlrc_disable_rules")
167
- assert_ran_ok(result)
168
- assert_rules_disabled(result, ["MD001", "MD002"])
169
- assert_rules_enabled(result, ["MD003", "MD004"])
132
+ result = run_cli_with_custom_rc_file("-l", "mdlrc_disable_rules")
133
+ assert_correctly_disabled(result)
134
+ end
135
+
136
+ def test_mdlrc_loading_from_current_dir_by_default
137
+ inside_tmp_dir do |dir|
138
+ with_mdlrc("mdlrc_disable_rules", dir) do
139
+ result = run_cli_without_rc_flag("-l")
140
+ assert_correctly_disabled(result)
141
+ end
142
+ end
143
+ end
144
+
145
+ def test_mdlrc_loading_ascends_until_it_finds_an_rc_file
146
+ Dir.mktmpdir do |parent_dir|
147
+ inside_tmp_dir(parent_dir) do
148
+ with_mdlrc("mdlrc_disable_rules", parent_dir) do
149
+ result = run_cli_without_rc_flag("-l")
150
+ assert_correctly_disabled(result)
151
+ end
152
+ end
153
+ end
170
154
  end
171
155
 
172
156
  def test_tag_inclusion_config
173
- result = run_cli("-l", "", "mdlrc_enable_tags")
157
+ result = run_cli_with_custom_rc_file("-l", "mdlrc_enable_tags")
174
158
  assert_ran_ok(result)
175
159
  assert_rules_enabled(result, ["MD001", "MD002", "MD009", "MD010"])
176
160
  assert_rules_disabled(result, ["MD004", "MD005"])
177
161
  end
178
162
 
179
163
  def test_tag_exclusion_config
180
- result = run_cli("-l", "", "mdlrc_disable_tags")
164
+ result = run_cli_with_custom_rc_file("-l", "mdlrc_disable_tags")
181
165
  assert_ran_ok(result)
182
166
  assert_rules_enabled(result, ["MD004", "MD030", "MD032"])
183
167
  assert_rules_disabled(result, ["MD001", "MD005"])
@@ -202,4 +186,108 @@ class TestCli < Minitest::Test
202
186
  files_with_issues = result[:stdout].split("\n").map { |l| l.split(":")[0] }.sort
203
187
  assert_equal(files_with_issues, ["#{path}/bar.markdown", "#{path}/foo.md"])
204
188
  end
189
+
190
+ def test_ignore_front_matter
191
+ path = File.expand_path("./fixtures/front_matter", File.dirname(__FILE__))
192
+ result = run_cli("-i -r MD001,MD041,MD034 #{path}")
193
+ assert_equal(result[:stdout], "#{path}/jekyll_post.md:16: MD001 Header levels should only increment by one level at a time\n")
194
+ end
195
+
196
+ private
197
+
198
+ def run_cli_with_input(args, stdin)
199
+ run_cmd("#{mdl_script} -c #{default_rc_file} #{args}", stdin)
200
+ end
201
+
202
+ def run_cli_without_rc_flag(args)
203
+ run_cmd("#{mdl_script} #{args}", "")
204
+ end
205
+
206
+ def run_cli(args)
207
+ run_cmd("#{mdl_script} -c #{default_rc_file} #{args}", "")
208
+ end
209
+
210
+ def run_cli_with_custom_rc_file(args, filename)
211
+ run_cmd("#{mdl_script} -c #{fixture_rc(filename)} #{args}", "")
212
+ end
213
+
214
+ def run_cli_with_file_and_ascii_env(content)
215
+ Tempfile.create('foo') do |f|
216
+ f.write(content)
217
+ f.close
218
+
219
+ run_cmd("ruby -E ASCII #{mdl_script} -c #{default_rc_file} #{f.path}", "")
220
+ end
221
+ end
222
+
223
+ def run_cmd(command, stdin)
224
+ result = {}
225
+ result[:stdout], result[:stderr], result[:status] = \
226
+ Open3.capture3("bundle", "exec", *command.split, :stdin_data => stdin)
227
+ result[:status] = result[:status].exitstatus
228
+ result
229
+ end
230
+
231
+ def mdl_script
232
+ File.expand_path("../../bin/mdl", __FILE__)
233
+ end
234
+
235
+ def fixture_rc(filename)
236
+ File.expand_path("../fixtures/#{filename}", __FILE__)
237
+ end
238
+
239
+ def default_rc_file
240
+ fixture_rc("default_mdlrc")
241
+ end
242
+
243
+ def inside_tmp_dir(base_dir = Dir.tmpdir)
244
+ Dir.mktmpdir(nil, base_dir) do |dir|
245
+ Dir.chdir(dir) { yield(dir) }
246
+ end
247
+ end
248
+
249
+ def assert_rules_enabled(result, rules, only_these_rules=false)
250
+ # Asserts that the given rules are enabled given the output of mdl -l
251
+ # If only_these_rules is set, then it asserts that the given rules and no
252
+ # others are enabled.
253
+ lines = result[:stdout].split("\n")
254
+ assert_equal("Enabled rules:", lines.first)
255
+ lines.shift
256
+ rules = rules.to_set
257
+ enabled_rules = lines.map{ |l| l.split(" ").first }.to_set
258
+ if only_these_rules
259
+ assert_equal(rules, enabled_rules)
260
+ else
261
+ assert_equal(Set.new, rules - enabled_rules)
262
+ end
263
+ end
264
+
265
+ def assert_rules_disabled(result, rules)
266
+ # Asserts that the given rules are _not_ enabled given the output of mdl -l
267
+ lines = result[:stdout].split("\n")
268
+ assert_equal("Enabled rules:", lines.first)
269
+ lines.shift
270
+ rules = rules.to_set
271
+ enabled_rules = lines.map{ |l| l.split(" ").first }.to_set
272
+ assert_equal(Set.new, rules & enabled_rules)
273
+ end
274
+
275
+ def assert_ran_ok(result)
276
+ assert_equal(0, result[:status])
277
+ assert_equal("", result[:stderr])
278
+ end
279
+
280
+ def assert_correctly_disabled(result)
281
+ assert_ran_ok(result)
282
+ assert_rules_disabled(result, ["MD001", "MD002"])
283
+ assert_rules_enabled(result, ["MD003", "MD004"])
284
+ end
285
+
286
+ def with_mdlrc(filename, dest_dir = Dir.pwd)
287
+ rc_path = File.join(dest_dir, ".mdlrc")
288
+ FileUtils.cp(fixture_rc(filename), rc_path)
289
+ yield
290
+ ensure
291
+ File.delete(rc_path)
292
+ end
205
293
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mdl
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mark Harrison
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-03-20 00:00:00.000000000 Z
11
+ date: 2016-08-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: kramdown
@@ -16,102 +16,102 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.8'
19
+ version: '1.12'
20
20
  - - ">="
21
21
  - !ruby/object:Gem::Version
22
- version: 1.8.0
22
+ version: 1.12.0
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
26
26
  requirements:
27
27
  - - "~>"
28
28
  - !ruby/object:Gem::Version
29
- version: '1.8'
29
+ version: '1.12'
30
30
  - - ">="
31
31
  - !ruby/object:Gem::Version
32
- version: 1.8.0
32
+ version: 1.12.0
33
33
  - !ruby/object:Gem::Dependency
34
34
  name: mixlib-config
35
35
  requirement: !ruby/object:Gem::Requirement
36
36
  requirements:
37
37
  - - "~>"
38
38
  - !ruby/object:Gem::Version
39
- version: '2.1'
39
+ version: '2.2'
40
40
  - - ">="
41
41
  - !ruby/object:Gem::Version
42
- version: 2.1.0
42
+ version: 2.2.1
43
43
  type: :runtime
44
44
  prerelease: false
45
45
  version_requirements: !ruby/object:Gem::Requirement
46
46
  requirements:
47
47
  - - "~>"
48
48
  - !ruby/object:Gem::Version
49
- version: '2.1'
49
+ version: '2.2'
50
50
  - - ">="
51
51
  - !ruby/object:Gem::Version
52
- version: 2.1.0
52
+ version: 2.2.1
53
53
  - !ruby/object:Gem::Dependency
54
54
  name: mixlib-cli
55
55
  requirement: !ruby/object:Gem::Requirement
56
56
  requirements:
57
57
  - - "~>"
58
58
  - !ruby/object:Gem::Version
59
- version: '1.5'
59
+ version: '1.7'
60
60
  - - ">="
61
61
  - !ruby/object:Gem::Version
62
- version: 1.5.0
62
+ version: 1.7.0
63
63
  type: :runtime
64
64
  prerelease: false
65
65
  version_requirements: !ruby/object:Gem::Requirement
66
66
  requirements:
67
67
  - - "~>"
68
68
  - !ruby/object:Gem::Version
69
- version: '1.5'
69
+ version: '1.7'
70
70
  - - ">="
71
71
  - !ruby/object:Gem::Version
72
- version: 1.5.0
72
+ version: 1.7.0
73
73
  - !ruby/object:Gem::Dependency
74
74
  name: bundler
75
75
  requirement: !ruby/object:Gem::Requirement
76
76
  requirements:
77
77
  - - "~>"
78
78
  - !ruby/object:Gem::Version
79
- version: '1.5'
79
+ version: '1.12'
80
80
  type: :development
81
81
  prerelease: false
82
82
  version_requirements: !ruby/object:Gem::Requirement
83
83
  requirements:
84
84
  - - "~>"
85
85
  - !ruby/object:Gem::Version
86
- version: '1.5'
86
+ version: '1.12'
87
87
  - !ruby/object:Gem::Dependency
88
88
  name: rake
89
89
  requirement: !ruby/object:Gem::Requirement
90
90
  requirements:
91
91
  - - "~>"
92
92
  - !ruby/object:Gem::Version
93
- version: '10.0'
93
+ version: '11.2'
94
94
  type: :development
95
95
  prerelease: false
96
96
  version_requirements: !ruby/object:Gem::Requirement
97
97
  requirements:
98
98
  - - "~>"
99
99
  - !ruby/object:Gem::Version
100
- version: '10.0'
100
+ version: '11.2'
101
101
  - !ruby/object:Gem::Dependency
102
102
  name: minitest
103
103
  requirement: !ruby/object:Gem::Requirement
104
104
  requirements:
105
105
  - - "~>"
106
106
  - !ruby/object:Gem::Version
107
- version: '5.0'
107
+ version: '5.9'
108
108
  type: :development
109
109
  prerelease: false
110
110
  version_requirements: !ruby/object:Gem::Requirement
111
111
  requirements:
112
112
  - - "~>"
113
113
  - !ruby/object:Gem::Version
114
- version: '5.0'
114
+ version: '5.9'
115
115
  - !ruby/object:Gem::Dependency
116
116
  name: pry
117
117
  requirement: !ruby/object:Gem::Requirement
@@ -165,11 +165,14 @@ files:
165
165
  - test/fixtures/default_mdlrc
166
166
  - test/fixtures/dir_with_md_and_markdown/bar.markdown
167
167
  - test/fixtures/dir_with_md_and_markdown/foo.md
168
+ - test/fixtures/front_matter/jekyll_post.md
168
169
  - test/fixtures/mdlrc_disable_rules
169
170
  - test/fixtures/mdlrc_disable_tags
170
171
  - test/fixtures/mdlrc_enable_rules
171
172
  - test/fixtures/mdlrc_enable_tags
172
173
  - test/fixtures/my_ruleset.rb
174
+ - test/rule_tests/alternate_top_level_header.md
175
+ - test/rule_tests/alternate_top_level_header_style.rb
173
176
  - test/rule_tests/atx_closed_header_spacing.md
174
177
  - test/rule_tests/atx_header_spacing.md
175
178
  - test/rule_tests/blockquote_blank_lines.md
@@ -289,7 +292,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
289
292
  version: '0'
290
293
  requirements: []
291
294
  rubyforge_project:
292
- rubygems_version: 2.5.2
295
+ rubygems_version: 2.5.1
293
296
  signing_key:
294
297
  specification_version: 4
295
298
  summary: Markdown lint tool
@@ -297,11 +300,14 @@ test_files:
297
300
  - test/fixtures/default_mdlrc
298
301
  - test/fixtures/dir_with_md_and_markdown/bar.markdown
299
302
  - test/fixtures/dir_with_md_and_markdown/foo.md
303
+ - test/fixtures/front_matter/jekyll_post.md
300
304
  - test/fixtures/mdlrc_disable_rules
301
305
  - test/fixtures/mdlrc_disable_tags
302
306
  - test/fixtures/mdlrc_enable_rules
303
307
  - test/fixtures/mdlrc_enable_tags
304
308
  - test/fixtures/my_ruleset.rb
309
+ - test/rule_tests/alternate_top_level_header.md
310
+ - test/rule_tests/alternate_top_level_header_style.rb
305
311
  - test/rule_tests/atx_closed_header_spacing.md
306
312
  - test/rule_tests/atx_header_spacing.md
307
313
  - test/rule_tests/blockquote_blank_lines.md
@@ -398,4 +404,3 @@ test_files:
398
404
  - test/test_cli.rb
399
405
  - test/test_ruledocs.rb
400
406
  - test/test_rules.rb
401
- has_rdoc: