mdl 0.11.0 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/mdl/cli.rb +3 -3
- data/lib/mdl/doc.rb +7 -5
- data/lib/mdl/rules.rb +87 -28
- data/lib/mdl/ruleset.rb +28 -2
- data/lib/mdl/styles/cirosantilli.rb +4 -0
- data/lib/mdl/styles/relaxed.rb +1 -0
- data/lib/mdl/version.rb +1 -1
- data/lib/mdl.rb +39 -8
- data/mdl.gemspec +3 -2
- metadata +13 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 240bbb771676be213b572426ae6aa48dd810cb11769263a30ee1e2b98b6751d5
|
4
|
+
data.tar.gz: 0c474a99242d291a202b958294ba749977230b43b24a38342a00bc6675857d6b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 538a08a57be028038bc8e1fe72c241e81e57261b84a0b58efb6875b515c8b0dfb01715826959778c6d88a9c6bb2b799b668a1662ac09e1a9d1c8a8a67817addd
|
7
|
+
data.tar.gz: 3104fb8e6bd66686b6268a5a5cb31f4bbdcef9fa7f7190f31b60a99c5acc489c47f19998c5bf40f9eff064c0f71cbeb73a8cb164a04899bb57666d041e85c125
|
data/lib/mdl/cli.rb
CHANGED
@@ -145,10 +145,10 @@ module MarkdownLint
|
|
145
145
|
end
|
146
146
|
|
147
147
|
def self.toggle_list(parts, to_sym = false)
|
148
|
-
parts = parts.split(',') if parts.
|
149
|
-
if parts.
|
148
|
+
parts = parts.split(',') if parts.instance_of?(String)
|
149
|
+
if parts.instance_of?(Array)
|
150
150
|
inc = parts.reject { |p| p.start_with?('~') }
|
151
|
-
exc = parts.select { |p| p.start_with?('~') }.map { |p| p[1
|
151
|
+
exc = parts.select { |p| p.start_with?('~') }.map { |p| p[1..] }
|
152
152
|
if to_sym
|
153
153
|
inc.map!(&:to_sym)
|
154
154
|
exc.map!(&:to_sym)
|
data/lib/mdl/doc.rb
CHANGED
@@ -34,7 +34,9 @@ module MarkdownLint
|
|
34
34
|
else
|
35
35
|
@offset = 0
|
36
36
|
end
|
37
|
-
|
37
|
+
# The -1 is to cause split to preserve an extra entry in the array so we
|
38
|
+
# can tell if there's a final newline in the file or not.
|
39
|
+
@lines = text.split(/\R/, -1)
|
38
40
|
@parsed = Kramdown::Document.new(text, :input => 'MarkdownLint')
|
39
41
|
@elements = @parsed.root.children
|
40
42
|
add_annotations(@elements)
|
@@ -78,7 +80,7 @@ module MarkdownLint
|
|
78
80
|
|
79
81
|
def find_type_elements(type, nested = true, elements = @elements)
|
80
82
|
results = []
|
81
|
-
type = [type] if type.
|
83
|
+
type = [type] if type.instance_of?(Symbol)
|
82
84
|
elements.each do |e|
|
83
85
|
results.push(e) if type.include?(e.type)
|
84
86
|
if nested && !e.children.empty?
|
@@ -102,8 +104,8 @@ module MarkdownLint
|
|
102
104
|
type, nested_except = [], elements = @elements
|
103
105
|
)
|
104
106
|
results = []
|
105
|
-
type = [type] if type.
|
106
|
-
nested_except = [nested_except] if nested_except.
|
107
|
+
type = [type] if type.instance_of?(Symbol)
|
108
|
+
nested_except = [nested_except] if nested_except.instance_of?(Symbol)
|
107
109
|
elements.each do |e|
|
108
110
|
results.push(e) if type.include?(e.type)
|
109
111
|
next if nested_except.include?(e.type) || e.children.empty?
|
@@ -230,7 +232,7 @@ module MarkdownLint
|
|
230
232
|
|
231
233
|
lines = e.value.split("\n")
|
232
234
|
lines.each_with_index do |l, i|
|
233
|
-
matches << first_line + i if regex.match(l)
|
235
|
+
matches << (first_line + i) if regex.match(l)
|
234
236
|
end
|
235
237
|
end
|
236
238
|
matches
|
data/lib/mdl/rules.rb
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
docs do |id, description|
|
2
|
+
url_hash = [id.downcase,
|
3
|
+
description.downcase.gsub(/[^a-z]+/, '-')].join('---')
|
4
|
+
"https://github.com/markdownlint/markdownlint/blob/master/docs/RULES.md##{url_hash}"
|
5
|
+
end
|
6
|
+
|
1
7
|
rule 'MD001', 'Header levels should only increment by one level at a time' do
|
2
8
|
tags :headers
|
3
9
|
aliases 'header-increment'
|
@@ -62,7 +68,7 @@ end
|
|
62
68
|
rule 'MD004', 'Unordered list style' do
|
63
69
|
tags :bullet, :ul
|
64
70
|
aliases 'ul-style'
|
65
|
-
# :style can be one of :consistent, :asterisk, :plus, :dash
|
71
|
+
# :style can be one of :consistent, :asterisk, :plus, :dash, :sublist
|
66
72
|
params :style => :consistent
|
67
73
|
check do |doc|
|
68
74
|
bullets = doc.find_type_elements(:ul).map do |l|
|
@@ -71,15 +77,30 @@ rule 'MD004', 'Unordered list style' do
|
|
71
77
|
if bullets.empty?
|
72
78
|
nil
|
73
79
|
else
|
74
|
-
doc_style =
|
80
|
+
doc_style = case @params[:style]
|
81
|
+
when :consistent
|
75
82
|
doc.list_style(bullets.first)
|
83
|
+
when :sublist
|
84
|
+
{}
|
76
85
|
else
|
77
86
|
@params[:style]
|
78
87
|
end
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
88
|
+
results = []
|
89
|
+
bullets.each do |b|
|
90
|
+
if @params[:style] == :sublist
|
91
|
+
level = b.options[:element_level]
|
92
|
+
if doc_style[level]
|
93
|
+
if doc_style[level] != doc.list_style(b)
|
94
|
+
results << doc.element_linenumber(b)
|
95
|
+
end
|
96
|
+
else
|
97
|
+
doc_style[level] = doc.list_style(b)
|
98
|
+
end
|
99
|
+
elsif doc.list_style(b) != doc_style
|
100
|
+
results << doc.element_linenumber(b)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
results.compact
|
83
104
|
end
|
84
105
|
end
|
85
106
|
end
|
@@ -119,7 +140,8 @@ end
|
|
119
140
|
rule 'MD007', 'Unordered list indentation' do
|
120
141
|
tags :bullet, :ul, :indentation
|
121
142
|
aliases 'ul-indent'
|
122
|
-
|
143
|
+
# Do not default to < 3, see PR#373 or the comments in RULES.md
|
144
|
+
params :indent => 3
|
123
145
|
check do |doc|
|
124
146
|
errors = []
|
125
147
|
indents = doc.find_type(:ul).map do |e|
|
@@ -152,8 +174,20 @@ end
|
|
152
174
|
rule 'MD010', 'Hard tabs' do
|
153
175
|
tags :whitespace, :hard_tab
|
154
176
|
aliases 'no-hard-tabs'
|
177
|
+
params :ignore_code_blocks => false
|
155
178
|
check do |doc|
|
156
|
-
|
179
|
+
# Every line in the document that is part of a code block. Blank lines
|
180
|
+
# inside of a code block are acceptable.
|
181
|
+
codeblock_lines = doc.find_type_elements(:codeblock).map do |e|
|
182
|
+
(doc.element_linenumber(e)..
|
183
|
+
doc.element_linenumber(e) + e.value.lines.count).to_a
|
184
|
+
end.flatten
|
185
|
+
|
186
|
+
# Check for lines with hard tab
|
187
|
+
hard_tab_lines = doc.matching_lines(/\t/)
|
188
|
+
# Remove lines with hard tabs, if they stem from codeblock
|
189
|
+
hard_tab_lines -= codeblock_lines if params[:ignore_code_blocks]
|
190
|
+
hard_tab_lines
|
157
191
|
end
|
158
192
|
end
|
159
193
|
|
@@ -186,7 +220,9 @@ end
|
|
186
220
|
rule 'MD013', 'Line length' do
|
187
221
|
tags :line_length
|
188
222
|
aliases 'line-length'
|
189
|
-
params :line_length => 80, :
|
223
|
+
params :line_length => 80, :ignore_code_blocks => false, :code_blocks => true,
|
224
|
+
:tables => true
|
225
|
+
|
190
226
|
check do |doc|
|
191
227
|
# Every line in the document that is part of a code block.
|
192
228
|
codeblock_lines = doc.find_type_elements(:codeblock).map do |e|
|
@@ -207,7 +243,14 @@ rule 'MD013', 'Line length' do
|
|
207
243
|
end
|
208
244
|
end.flatten
|
209
245
|
overlines = doc.matching_lines(/^.{#{@params[:line_length]}}.*\s/)
|
210
|
-
|
246
|
+
if !params[:code_blocks] || params[:ignore_code_blocks]
|
247
|
+
overlines -= codeblock_lines
|
248
|
+
unless params[:code_blocks]
|
249
|
+
warn 'MD013 warning: Parameter :code_blocks is deprecated.'
|
250
|
+
warn ' Please replace \":code_blocks => false\" by '\
|
251
|
+
'\":ignore_code_blocks => true\" in your configuration.'
|
252
|
+
end
|
253
|
+
end
|
211
254
|
overlines -= table_lines unless params[:tables]
|
212
255
|
overlines
|
213
256
|
end
|
@@ -218,7 +261,7 @@ rule 'MD014', 'Dollar signs used before commands without showing output' do
|
|
218
261
|
aliases 'commands-show-output'
|
219
262
|
check do |doc|
|
220
263
|
doc.find_type_elements(:codeblock).select do |e|
|
221
|
-
!e.value.empty?
|
264
|
+
!e.value.empty? &&
|
222
265
|
!e.value.split(/\n+/).map { |l| l.match(/^\$\s/) }.include?(nil)
|
223
266
|
end.map { |e| doc.element_linenumber(e) }
|
224
267
|
end
|
@@ -229,7 +272,7 @@ rule 'MD018', 'No space after hash on atx style header' do
|
|
229
272
|
aliases 'no-missing-space-atx'
|
230
273
|
check do |doc|
|
231
274
|
doc.find_type_elements(:header).select do |h|
|
232
|
-
doc.header_style(h) == :atx
|
275
|
+
doc.header_style(h) == :atx && doc.element_line(h).match(/^#+[^#\s]/)
|
233
276
|
end.map { |h| doc.element_linenumber(h) }
|
234
277
|
end
|
235
278
|
end
|
@@ -239,7 +282,7 @@ rule 'MD019', 'Multiple spaces after hash on atx style header' do
|
|
239
282
|
aliases 'no-multiple-space-atx'
|
240
283
|
check do |doc|
|
241
284
|
doc.find_type_elements(:header).select do |h|
|
242
|
-
doc.header_style(h) == :atx
|
285
|
+
doc.header_style(h) == :atx && doc.element_line(h).match(/^#+\s\s/)
|
243
286
|
end.map { |h| doc.element_linenumber(h) }
|
244
287
|
end
|
245
288
|
end
|
@@ -250,8 +293,8 @@ rule 'MD020', 'No space inside hashes on closed atx style header' do
|
|
250
293
|
check do |doc|
|
251
294
|
doc.find_type_elements(:header).select do |h|
|
252
295
|
doc.header_style(h) == :atx_closed \
|
253
|
-
|
254
|
-
|
296
|
+
&& (doc.element_line(h).match(/^#+[^#\s]/) \
|
297
|
+
|| doc.element_line(h).match(/[^#\s\\]#+$/))
|
255
298
|
end.map { |h| doc.element_linenumber(h) }
|
256
299
|
end
|
257
300
|
end
|
@@ -262,8 +305,8 @@ rule 'MD021', 'Multiple spaces inside hashes on closed atx style header' do
|
|
262
305
|
check do |doc|
|
263
306
|
doc.find_type_elements(:header).select do |h|
|
264
307
|
doc.header_style(h) == :atx_closed \
|
265
|
-
|
266
|
-
|
308
|
+
&& (doc.element_line(h).match(/^#+\s\s/) \
|
309
|
+
|| doc.element_line(h).match(/\s\s#+$/))
|
267
310
|
end.map { |h| doc.element_linenumber(h) }
|
268
311
|
end
|
269
312
|
end
|
@@ -297,7 +340,7 @@ rule 'MD022', 'Headers should be surrounded by blank lines' do
|
|
297
340
|
errors << linenum if line.match(/^\#{1,6}/) && !prev_lines[1].empty?
|
298
341
|
# Next, look for setext style
|
299
342
|
if line.match(/^(-+|=+)\s*$/) && !prev_lines[0].empty?
|
300
|
-
errors << linenum - 1
|
343
|
+
errors << (linenum - 1)
|
301
344
|
end
|
302
345
|
linenum += 1
|
303
346
|
prev_lines << line
|
@@ -329,7 +372,7 @@ rule 'MD023', 'Headers must start at the beginning of the line' do
|
|
329
372
|
errors << linenum if line.match(/^\s+\#{1,6}/)
|
330
373
|
# Next, look for setext style
|
331
374
|
if line.match(/^\s+(-+|=+)\s*$/) && !prev_line.empty?
|
332
|
-
errors << linenum - 1
|
375
|
+
errors << (linenum - 1)
|
333
376
|
end
|
334
377
|
linenum += 1
|
335
378
|
prev_line = line
|
@@ -390,7 +433,7 @@ rule 'MD025', 'Multiple top level headers in the same document' do
|
|
390
433
|
h[:level] == params[:level]
|
391
434
|
end
|
392
435
|
if !headers.empty? && (doc.element_linenumber(headers[0]) == 1)
|
393
|
-
headers[1
|
436
|
+
headers[1..].map { |h| doc.element_linenumber(h) }
|
394
437
|
end
|
395
438
|
end
|
396
439
|
end
|
@@ -438,7 +481,7 @@ rule 'MD028', 'Blank line inside blockquote' do
|
|
438
481
|
# The current location is the start of the second blockquote, so the
|
439
482
|
# line before will be a blank line in between the two, or at least the
|
440
483
|
# lowest blank line if there are more than one.
|
441
|
-
errors << e.options[:location] - 1
|
484
|
+
errors << (e.options[:location] - 1)
|
442
485
|
end
|
443
486
|
check_blockquote(errors, e.children)
|
444
487
|
end
|
@@ -490,8 +533,13 @@ rule 'MD030', 'Spaces after list markers' do
|
|
490
533
|
# the items in it have multiple paragraphs/other block items.
|
491
534
|
srule = items.map { |i| i.children.length }.max > 1 ? 'multi' : 'single'
|
492
535
|
items.each do |i|
|
493
|
-
|
494
|
-
|
536
|
+
line = doc.element_line(i)
|
537
|
+
# See #278 - sometimes we think non-printable characters are list
|
538
|
+
# items even if they are not, so this ignore those and prevents
|
539
|
+
# us from crashing
|
540
|
+
next if line.empty?
|
541
|
+
|
542
|
+
actual_spaces = line.gsub(/^> /, '').match(/^\s*\S+(\s+)/)[1].length
|
495
543
|
required_spaces = params["#{list_type}_#{srule}".to_sym]
|
496
544
|
errors << doc.element_linenumber(i) if required_spaces != actual_spaces
|
497
545
|
end
|
@@ -548,7 +596,7 @@ rule 'MD032', 'Lists should be surrounded by blank lines' do
|
|
548
596
|
unless in_code
|
549
597
|
list_marker = line.strip.match(/^([*+\-]|(\d+\.))\s/)
|
550
598
|
if list_marker && !in_list && !prev_line.match(/^($|\s)/)
|
551
|
-
errors << linenum + 1
|
599
|
+
errors << (linenum + 1)
|
552
600
|
elsif !list_marker && in_list && !line.match(/^($|\s)/)
|
553
601
|
errors << linenum
|
554
602
|
end
|
@@ -648,7 +696,7 @@ rule 'MD038', 'Spaces inside code span elements' do
|
|
648
696
|
# block that happen to be parsed as code spans.
|
649
697
|
doc.element_linenumbers(
|
650
698
|
doc.find_type_elements(:codespan).select do |i|
|
651
|
-
i.value.match(/(^\s|\s$)/)
|
699
|
+
i.value.match(/(^\s|\s$)/) && !i.value.include?("\n")
|
652
700
|
end,
|
653
701
|
)
|
654
702
|
end
|
@@ -660,8 +708,8 @@ rule 'MD039', 'Spaces inside link text' do
|
|
660
708
|
check do |doc|
|
661
709
|
doc.element_linenumbers(
|
662
710
|
doc.find_type_elements(:a).reject { |e| e.children.empty? }.select do |e|
|
663
|
-
e.children.first.type == :text && e.children.last.type == :text
|
664
|
-
e.children.first.value.start_with?(' ')
|
711
|
+
e.children.first.type == :text && e.children.last.type == :text && (
|
712
|
+
e.children.first.value.start_with?(' ') ||
|
665
713
|
e.children.last.value.end_with?(' '))
|
666
714
|
end,
|
667
715
|
)
|
@@ -675,7 +723,7 @@ rule 'MD040', 'Fenced code blocks should have a language specified' do
|
|
675
723
|
# Kramdown parses code blocks with language settings as code blocks with
|
676
724
|
# the class attribute set to language-languagename.
|
677
725
|
doc.element_linenumbers(doc.find_type_elements(:codeblock).select do |i|
|
678
|
-
!i.attr['class'].to_s.start_with?('language-')
|
726
|
+
!i.attr['class'].to_s.start_with?('language-') &&
|
679
727
|
!doc.element_line(i).start_with?(' ')
|
680
728
|
end)
|
681
729
|
end
|
@@ -731,3 +779,14 @@ rule 'MD046', 'Code block style' do
|
|
731
779
|
)
|
732
780
|
end
|
733
781
|
end
|
782
|
+
|
783
|
+
rule 'MD047', 'File should end with a single newline character' do
|
784
|
+
tags :blank_lines
|
785
|
+
aliases 'single-trailing-newline'
|
786
|
+
check do |doc|
|
787
|
+
error_lines = []
|
788
|
+
last_line = doc.lines[-1]
|
789
|
+
error_lines.push(doc.lines.length) unless last_line.nil? || last_line.empty?
|
790
|
+
error_lines
|
791
|
+
end
|
792
|
+
end
|
data/lib/mdl/ruleset.rb
CHANGED
@@ -3,9 +3,11 @@ module MarkdownLint
|
|
3
3
|
class Rule
|
4
4
|
attr_accessor :id, :description
|
5
5
|
|
6
|
-
def initialize(id, description, block)
|
6
|
+
def initialize(id, description, fallback_docs: nil, &block)
|
7
7
|
@id = id
|
8
8
|
@description = description
|
9
|
+
@generate_docs = fallback_docs
|
10
|
+
@docs_overridden = false
|
9
11
|
@aliases = []
|
10
12
|
@tags = []
|
11
13
|
@params = {}
|
@@ -31,6 +33,21 @@ module MarkdownLint
|
|
31
33
|
@params.update(params) unless params.nil?
|
32
34
|
@params
|
33
35
|
end
|
36
|
+
|
37
|
+
def docs(url = nil, &block)
|
38
|
+
if block_given? != url.nil?
|
39
|
+
raise ArgumentError, 'Give either a URL or a block, not both'
|
40
|
+
end
|
41
|
+
|
42
|
+
raise 'A docs url is already set within this rule' if @docs_overridden
|
43
|
+
|
44
|
+
@generate_docs = block_given? ? block : lambda { |_, _| url }
|
45
|
+
@docs_overridden = true
|
46
|
+
end
|
47
|
+
|
48
|
+
def docs_url
|
49
|
+
@generate_docs&.call(id, description)
|
50
|
+
end
|
34
51
|
end
|
35
52
|
|
36
53
|
# defines a ruleset
|
@@ -42,7 +59,8 @@ module MarkdownLint
|
|
42
59
|
end
|
43
60
|
|
44
61
|
def rule(id, description, &block)
|
45
|
-
@rules[id] =
|
62
|
+
@rules[id] =
|
63
|
+
Rule.new(id, description, :fallback_docs => @fallback_docs, &block)
|
46
64
|
end
|
47
65
|
|
48
66
|
def load(rules_file)
|
@@ -50,6 +68,14 @@ module MarkdownLint
|
|
50
68
|
@rules
|
51
69
|
end
|
52
70
|
|
71
|
+
def docs(url = nil, &block)
|
72
|
+
if block_given? != url.nil?
|
73
|
+
raise ArgumentError, 'Give either a URL or a block, not both'
|
74
|
+
end
|
75
|
+
|
76
|
+
@fallback_docs = block_given? ? block : lambda { |_, _| url }
|
77
|
+
end
|
78
|
+
|
53
79
|
def load_default
|
54
80
|
load(File.expand_path('rules.rb', __dir__))
|
55
81
|
end
|
@@ -9,3 +9,7 @@ rule 'MD035', :style => '---'
|
|
9
9
|
# Inline HTML - this isn't forbidden by the style guide, and raw HTML use is
|
10
10
|
# explicitly mentioned in the 'email automatic links' section.
|
11
11
|
exclude_rule 'MD033'
|
12
|
+
|
13
|
+
# File should end with a single newline character
|
14
|
+
# this isn't forbidden by the style guide
|
15
|
+
exclude_rule 'MD047'
|
data/lib/mdl/styles/relaxed.rb
CHANGED
@@ -8,3 +8,4 @@ exclude_rule 'MD033' # Inline HTML
|
|
8
8
|
exclude_rule 'MD034' # Bare URL used
|
9
9
|
exclude_rule 'MD040' # Fenced code blocks should have a language specified
|
10
10
|
exclude_rule 'MD041' # First line in file should be a top level header
|
11
|
+
exclude_rule 'MD047' # File should end with a single newline character
|
data/lib/mdl/version.rb
CHANGED
data/lib/mdl.rb
CHANGED
@@ -66,7 +66,8 @@ module MarkdownLint
|
|
66
66
|
Dir.chdir(filename) do
|
67
67
|
cli.cli_arguments[i] =
|
68
68
|
Mixlib::ShellOut.new("git ls-files '*.md' '*.markdown'")
|
69
|
-
.run_command.stdout.lines
|
69
|
+
.run_command.stdout.lines
|
70
|
+
.map { |m| File.join(filename, m.strip) }
|
70
71
|
end
|
71
72
|
else
|
72
73
|
cli.cli_arguments[i] = Dir["#{filename}/**/*.{md,markdown}"]
|
@@ -77,8 +78,15 @@ module MarkdownLint
|
|
77
78
|
|
78
79
|
status = 0
|
79
80
|
results = []
|
81
|
+
docs_to_print = []
|
80
82
|
cli.cli_arguments.each do |filename|
|
81
83
|
puts "Checking #{filename}..." if Config[:verbose]
|
84
|
+
unless filename == '-' || File.exist?(filename)
|
85
|
+
warn(
|
86
|
+
"#{Errno::ENOENT}: No such file or directory - #{filename}",
|
87
|
+
)
|
88
|
+
exit 3
|
89
|
+
end
|
82
90
|
doc = Doc.new_from_file(filename, Config[:ignore_front_matter])
|
83
91
|
filename = '(stdin)' if filename == '-'
|
84
92
|
if Config[:show_kramdown_warnings]
|
@@ -102,24 +110,47 @@ module MarkdownLint
|
|
102
110
|
'rule' => id,
|
103
111
|
'aliases' => rule.aliases,
|
104
112
|
'description' => rule.description,
|
113
|
+
'docs' => rule.docs_url,
|
105
114
|
}
|
106
|
-
elsif Config[:show_aliases]
|
107
|
-
puts "#{filename}:#{line}: #{rule.aliases.first || id} " +
|
108
|
-
rule.description.to_s
|
109
115
|
else
|
110
|
-
|
116
|
+
linked_id = linkify(printable_id(rule), rule.docs_url)
|
117
|
+
puts "#{filename}:#{line}: #{linked_id} " + rule.description.to_s
|
111
118
|
end
|
112
119
|
end
|
120
|
+
|
121
|
+
# If we're not in JSON mode (URLs are in the object), and we cannot
|
122
|
+
# make real links (checking if we have a TTY is an OK heuristic for
|
123
|
+
# that) then, instead of making the output ugly with long URLs, we
|
124
|
+
# print them at the end. And of course we only want to print each URL
|
125
|
+
# once.
|
126
|
+
if !Config[:json] && !$stdout.tty? && !docs_to_print.include?(rule)
|
127
|
+
docs_to_print << rule
|
128
|
+
end
|
113
129
|
end
|
114
130
|
end
|
115
131
|
|
116
132
|
if Config[:json]
|
117
133
|
require 'json'
|
118
134
|
puts JSON.generate(results)
|
119
|
-
elsif
|
120
|
-
puts "\
|
121
|
-
|
135
|
+
elsif docs_to_print.any?
|
136
|
+
puts "\nFurther documentation is available for these failures:"
|
137
|
+
docs_to_print.each do |rule|
|
138
|
+
puts " - #{printable_id(rule)}: #{rule.docs_url}"
|
139
|
+
end
|
122
140
|
end
|
123
141
|
exit status
|
124
142
|
end
|
143
|
+
|
144
|
+
def self.printable_id(rule)
|
145
|
+
return rule.aliases.first if Config[:show_aliases] && rule.aliases.any?
|
146
|
+
|
147
|
+
rule.id
|
148
|
+
end
|
149
|
+
|
150
|
+
# Creates hyperlinks in terminal emulators, if available: https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda
|
151
|
+
def self.linkify(text, url)
|
152
|
+
return text unless $stdout.tty? && url
|
153
|
+
|
154
|
+
"\e]8;;#{url}\e\\#{text}\e]8;;\e\\"
|
155
|
+
end
|
125
156
|
end
|
data/mdl.gemspec
CHANGED
@@ -11,6 +11,7 @@ Gem::Specification.new do |spec|
|
|
11
11
|
spec.description = 'Style checker/lint tool for markdown files'
|
12
12
|
spec.homepage = 'http://github.com/markdownlint/markdownlint'
|
13
13
|
spec.license = 'MIT'
|
14
|
+
spec.metadata['rubygems_mfa_required'] = 'true'
|
14
15
|
|
15
16
|
spec.files = %w{LICENSE.txt Gemfile} + Dir.glob('*.gemspec') +
|
16
17
|
Dir.glob('lib/**/*')
|
@@ -18,7 +19,7 @@ Gem::Specification.new do |spec|
|
|
18
19
|
spec.executables = %w{mdl}
|
19
20
|
spec.require_paths = ['lib']
|
20
21
|
|
21
|
-
spec.required_ruby_version = '>= 2.
|
22
|
+
spec.required_ruby_version = '>= 2.7'
|
22
23
|
|
23
24
|
spec.add_dependency 'kramdown', '~> 2.3'
|
24
25
|
spec.add_dependency 'kramdown-parser-gfm', '~> 1.1'
|
@@ -30,5 +31,5 @@ Gem::Specification.new do |spec|
|
|
30
31
|
spec.add_development_dependency 'minitest', '~> 5.9'
|
31
32
|
spec.add_development_dependency 'pry', '~> 0.10'
|
32
33
|
spec.add_development_dependency 'rake', '>= 11.2', '< 14'
|
33
|
-
spec.add_development_dependency 'rubocop', '
|
34
|
+
spec.add_development_dependency 'rubocop', '~> 1.28.1'
|
34
35
|
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.
|
4
|
+
version: 0.12.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mark Harrison
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-10-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: kramdown
|
@@ -164,16 +164,16 @@ dependencies:
|
|
164
164
|
name: rubocop
|
165
165
|
requirement: !ruby/object:Gem::Requirement
|
166
166
|
requirements:
|
167
|
-
- - "
|
167
|
+
- - "~>"
|
168
168
|
- !ruby/object:Gem::Version
|
169
|
-
version:
|
169
|
+
version: 1.28.1
|
170
170
|
type: :development
|
171
171
|
prerelease: false
|
172
172
|
version_requirements: !ruby/object:Gem::Requirement
|
173
173
|
requirements:
|
174
|
-
- - "
|
174
|
+
- - "~>"
|
175
175
|
- !ruby/object:Gem::Version
|
176
|
-
version:
|
176
|
+
version: 1.28.1
|
177
177
|
description: Style checker/lint tool for markdown files
|
178
178
|
email:
|
179
179
|
- mark@mivok.net
|
@@ -202,8 +202,9 @@ files:
|
|
202
202
|
homepage: http://github.com/markdownlint/markdownlint
|
203
203
|
licenses:
|
204
204
|
- MIT
|
205
|
-
metadata:
|
206
|
-
|
205
|
+
metadata:
|
206
|
+
rubygems_mfa_required: 'true'
|
207
|
+
post_install_message:
|
207
208
|
rdoc_options: []
|
208
209
|
require_paths:
|
209
210
|
- lib
|
@@ -211,15 +212,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
211
212
|
requirements:
|
212
213
|
- - ">="
|
213
214
|
- !ruby/object:Gem::Version
|
214
|
-
version: '2.
|
215
|
+
version: '2.7'
|
215
216
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
216
217
|
requirements:
|
217
218
|
- - ">="
|
218
219
|
- !ruby/object:Gem::Version
|
219
220
|
version: '0'
|
220
221
|
requirements: []
|
221
|
-
rubygems_version: 3.
|
222
|
-
signing_key:
|
222
|
+
rubygems_version: 3.3.7
|
223
|
+
signing_key:
|
223
224
|
specification_version: 4
|
224
225
|
summary: Markdown lint tool
|
225
226
|
test_files: []
|