mdl 0.9.0 → 0.10.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.
@@ -5,8 +5,8 @@ require 'kramdown/parser/gfm'
5
5
 
6
6
  module Kramdown
7
7
  module Parser
8
+ # modified parser class - see comment above
8
9
  class MarkdownLint < Kramdown::Parser::Kramdown
9
-
10
10
  def initialize(source, options)
11
11
  super
12
12
  i = @block_parsers.index(:codeblock_fenced)
@@ -1,4 +1,4 @@
1
- rule "MD001", "Header levels should only increment by one level at a time" do
1
+ rule 'MD001', 'Header levels should only increment by one level at a time' do
2
2
  tags :headers
3
3
  aliases 'header-increment'
4
4
  check do |doc|
@@ -6,26 +6,26 @@ rule "MD001", "Header levels should only increment by one level at a time" do
6
6
  old_level = nil
7
7
  errors = []
8
8
  headers.each do |h|
9
- if old_level and h[:level] > old_level + 1
10
- errors << h[:location]
11
- end
9
+ errors << h[:location] if old_level && (h[:level] > old_level + 1)
12
10
  old_level = h[:level]
13
11
  end
14
12
  errors
15
13
  end
16
14
  end
17
15
 
18
- rule "MD002", "First header should be a top level header" do
16
+ rule 'MD002', 'First header should be a top level header' do
19
17
  tags :headers
20
18
  aliases 'first-header-h1'
21
19
  params :level => 1
22
20
  check do |doc|
23
21
  first_header = doc.find_type(:header).first
24
- [first_header[:location]] if first_header and first_header[:level] != @params[:level]
22
+ if first_header && (first_header[:level] != @params[:level])
23
+ [first_header[:location]]
24
+ end
25
25
  end
26
26
  end
27
27
 
28
- rule "MD003", "Header style" do
28
+ rule 'MD003', 'Header style' do
29
29
  # Header styles are things like ### and adding underscores
30
30
  # See http://daringfireball.net/projects/markdown/syntax#header
31
31
  tags :headers
@@ -37,47 +37,54 @@ rule "MD003", "Header style" do
37
37
  if headers.empty?
38
38
  nil
39
39
  else
40
- if @params[:style] == :consistent
41
- doc_style = doc.header_style(headers.first)
42
- else
43
- doc_style = @params[:style]
44
- end
40
+ doc_style = if @params[:style] == :consistent
41
+ doc.header_style(headers.first)
42
+ else
43
+ @params[:style]
44
+ end
45
45
  if doc_style == :setext_with_atx
46
- headers.map { |h| doc.element_linenumber(h) \
47
- unless doc.header_style(h) == :setext or \
48
- (doc.header_style(h) == :atx and \
49
- h.options[:level] > 2) }.compact
46
+ headers.map do |h|
47
+ doc.element_linenumber(h) \
48
+ unless (doc.header_style(h) == :setext) || \
49
+ ((doc.header_style(h) == :atx) && \
50
+ (h.options[:level] > 2))
51
+ end.compact
50
52
  else
51
- headers.map { |h| doc.element_linenumber(h) \
52
- if doc.header_style(h) != doc_style }.compact
53
+ headers.map do |h|
54
+ doc.element_linenumber(h) \
55
+ if doc.header_style(h) != doc_style
56
+ end.compact
53
57
  end
54
58
  end
55
59
  end
56
60
  end
57
61
 
58
- rule "MD004", "Unordered list style" do
62
+ rule 'MD004', 'Unordered list style' do
59
63
  tags :bullet, :ul
60
64
  aliases 'ul-style'
61
65
  # :style can be one of :consistent, :asterisk, :plus, :dash
62
66
  params :style => :consistent
63
67
  check do |doc|
64
- bullets = doc.find_type_elements(:ul).map {|l|
65
- doc.find_type_elements(:li, false, l.children)}.flatten
68
+ bullets = doc.find_type_elements(:ul).map do |l|
69
+ doc.find_type_elements(:li, false, l.children)
70
+ end.flatten
66
71
  if bullets.empty?
67
72
  nil
68
73
  else
69
- if @params[:style] == :consistent
70
- doc_style = doc.list_style(bullets.first)
71
- else
72
- doc_style = @params[:style]
73
- end
74
- bullets.map { |b| doc.element_linenumber(b) \
75
- if doc.list_style(b) != doc_style }.compact
74
+ doc_style = if @params[:style] == :consistent
75
+ doc.list_style(bullets.first)
76
+ else
77
+ @params[:style]
78
+ end
79
+ bullets.map do |b|
80
+ doc.element_linenumber(b) \
81
+ if doc.list_style(b) != doc_style
82
+ end.compact
76
83
  end
77
84
  end
78
85
  end
79
86
 
80
- rule "MD005", "Inconsistent indentation for list items at the same level" do
87
+ rule 'MD005', 'Inconsistent indentation for list items at the same level' do
81
88
  tags :bullet, :ul, :indentation
82
89
  aliases 'list-indent'
83
90
  check do |doc|
@@ -97,29 +104,30 @@ rule "MD005", "Inconsistent indentation for list items at the same level" do
97
104
  end
98
105
  end
99
106
 
100
- rule "MD006", "Consider starting bulleted lists at the beginning of the line" do
107
+ rule 'MD006', 'Consider starting bulleted lists at the beginning of the line' do
101
108
  # Starting at the beginning of the line means that indendation for each
102
109
  # bullet level can be identical.
103
110
  tags :bullet, :ul, :indentation
104
111
  aliases 'ul-start-left'
105
112
  check do |doc|
106
- doc.find_type(:ul, false).select{
107
- |e| doc.indent_for(doc.element_line(e)) != 0 }.map{ |e| e[:location] }
113
+ doc.find_type(:ul, false).reject do |e|
114
+ doc.indent_for(doc.element_line(e)) == 0
115
+ end.map { |e| e[:location] }
108
116
  end
109
117
  end
110
118
 
111
- rule "MD007", "Unordered list indentation" do
119
+ rule 'MD007', 'Unordered list indentation' do
112
120
  tags :bullet, :ul, :indentation
113
121
  aliases 'ul-indent'
114
122
  params :indent => 2
115
123
  check do |doc|
116
- indents = []
117
124
  errors = []
118
- indents = doc.find_type(:ul).map {
119
- |e| [doc.indent_for(doc.element_line(e)), doc.element_linenumber(e)] }
125
+ indents = doc.find_type(:ul).map do |e|
126
+ [doc.indent_for(doc.element_line(e)), doc.element_linenumber(e)]
127
+ end
120
128
  curr_indent = indents[0][0] unless indents.empty?
121
129
  indents.each do |indent, linenum|
122
- if indent > curr_indent and indent - curr_indent != @params[:indent]
130
+ if (indent > curr_indent) && (indent - curr_indent != @params[:indent])
123
131
  errors << linenum
124
132
  end
125
133
  curr_indent = indent
@@ -128,7 +136,7 @@ rule "MD007", "Unordered list indentation" do
128
136
  end
129
137
  end
130
138
 
131
- rule "MD009", "Trailing spaces" do
139
+ rule 'MD009', 'Trailing spaces' do
132
140
  tags :whitespace
133
141
  aliases 'no-trailing-spaces'
134
142
  params :br_spaces => 0
@@ -141,7 +149,7 @@ rule "MD009", "Trailing spaces" do
141
149
  end
142
150
  end
143
151
 
144
- rule "MD010", "Hard tabs" do
152
+ rule 'MD010', 'Hard tabs' do
145
153
  tags :whitespace, :hard_tab
146
154
  aliases 'no-hard-tabs'
147
155
  check do |doc|
@@ -149,7 +157,7 @@ rule "MD010", "Hard tabs" do
149
157
  end
150
158
  end
151
159
 
152
- rule "MD011", "Reversed link syntax" do
160
+ rule 'MD011', 'Reversed link syntax' do
153
161
  tags :links
154
162
  aliases 'no-reversed-links'
155
163
  check do |doc|
@@ -157,39 +165,47 @@ rule "MD011", "Reversed link syntax" do
157
165
  end
158
166
  end
159
167
 
160
- rule "MD012", "Multiple consecutive blank lines" do
168
+ rule 'MD012', 'Multiple consecutive blank lines' do
161
169
  tags :whitespace, :blank_lines
162
170
  aliases 'no-multiple-blanks'
163
171
  check do |doc|
164
172
  # Every line in the document that is part of a code block. Blank lines
165
173
  # inside of a code block are acceptable.
166
- codeblock_lines = doc.find_type_elements(:codeblock).map{
167
- |e| (doc.element_linenumber(e)..
168
- doc.element_linenumber(e) + e.value.lines.count).to_a }.flatten
174
+ codeblock_lines = doc.find_type_elements(:codeblock).map do |e|
175
+ (doc.element_linenumber(e)..
176
+ doc.element_linenumber(e) + e.value.lines.count).to_a
177
+ end.flatten
169
178
  blank_lines = doc.matching_lines(/^\s*$/)
170
- cons_blank_lines = blank_lines.each_cons(2).select{
171
- |p, n| n - p == 1}.map{|p, n| n}
179
+ cons_blank_lines = blank_lines.each_cons(2).select do |p, n|
180
+ n - p == 1
181
+ end.map { |_p, n| n }
172
182
  cons_blank_lines - codeblock_lines
173
183
  end
174
184
  end
175
185
 
176
- rule "MD013", "Line length" do
186
+ rule 'MD013', 'Line length' do
177
187
  tags :line_length
178
188
  aliases 'line-length'
179
189
  params :line_length => 80, :code_blocks => true, :tables => true
180
190
  check do |doc|
181
191
  # Every line in the document that is part of a code block.
182
- codeblock_lines = doc.find_type_elements(:codeblock).map{
183
- |e| (doc.element_linenumber(e)..
184
- doc.element_linenumber(e) + e.value.lines.count).to_a }.flatten
192
+ codeblock_lines = doc.find_type_elements(:codeblock).map do |e|
193
+ (doc.element_linenumber(e)..
194
+ doc.element_linenumber(e) + e.value.lines.count).to_a
195
+ end.flatten
185
196
  # Every line in the document that is part of a table.
186
197
  locations = doc.elements
187
- .map { |e| [e.options[:location], e] }
188
- .reject { |l, _| l.nil? }
189
- table_lines = locations.map.with_index {
190
- |(l, e), i| (i + 1 < locations.size ?
191
- (l..locations[i+1].first - 1) :
192
- (l..doc.lines.count)).to_a if e.type == :table }.flatten
198
+ .map { |e| [e.options[:location], e] }
199
+ .reject { |l, _| l.nil? }
200
+ table_lines = locations.map.with_index do |(l, e), i|
201
+ if e.type == :table
202
+ if i + 1 < locations.size
203
+ (l..locations[i + 1].first - 1).to_a
204
+ else
205
+ (l..doc.lines.count).to_a
206
+ end
207
+ end
208
+ end.flatten
193
209
  overlines = doc.matching_lines(/^.{#{@params[:line_length]}}.*\s/)
194
210
  overlines -= codeblock_lines unless params[:code_blocks]
195
211
  overlines -= table_lines unless params[:tables]
@@ -197,18 +213,18 @@ rule "MD013", "Line length" do
197
213
  end
198
214
  end
199
215
 
200
- rule "MD014", "Dollar signs used before commands without showing output" do
216
+ rule 'MD014', 'Dollar signs used before commands without showing output' do
201
217
  tags :code
202
218
  aliases 'commands-show-output'
203
219
  check do |doc|
204
- doc.find_type_elements(:codeblock).select{
205
- |e| not e.value.empty? and
206
- not e.value.split(/\n+/).map{|l| l.match(/^\$\s/)}.include?(nil)
207
- }.map{|e| doc.element_linenumber(e)}
220
+ doc.find_type_elements(:codeblock).select do |e|
221
+ !e.value.empty? and
222
+ !e.value.split(/\n+/).map { |l| l.match(/^\$\s/) }.include?(nil)
223
+ end.map { |e| doc.element_linenumber(e) }
208
224
  end
209
225
  end
210
226
 
211
- rule "MD018", "No space after hash on atx style header" do
227
+ rule 'MD018', 'No space after hash on atx style header' do
212
228
  tags :headers, :atx, :spaces
213
229
  aliases 'no-missing-space-atx'
214
230
  check do |doc|
@@ -218,7 +234,7 @@ rule "MD018", "No space after hash on atx style header" do
218
234
  end
219
235
  end
220
236
 
221
- rule "MD019", "Multiple spaces after hash on atx style header" do
237
+ rule 'MD019', 'Multiple spaces after hash on atx style header' do
222
238
  tags :headers, :atx, :spaces
223
239
  aliases 'no-multiple-space-atx'
224
240
  check do |doc|
@@ -228,7 +244,7 @@ rule "MD019", "Multiple spaces after hash on atx style header" do
228
244
  end
229
245
  end
230
246
 
231
- rule "MD020", "No space inside hashes on closed atx style header" do
247
+ rule 'MD020', 'No space inside hashes on closed atx style header' do
232
248
  tags :headers, :atx_closed, :spaces
233
249
  aliases 'no-missing-space-closed-atx'
234
250
  check do |doc|
@@ -240,7 +256,7 @@ rule "MD020", "No space inside hashes on closed atx style header" do
240
256
  end
241
257
  end
242
258
 
243
- rule "MD021", "Multiple spaces inside hashes on closed atx style header" do
259
+ rule 'MD021', 'Multiple spaces inside hashes on closed atx style header' do
244
260
  tags :headers, :atx_closed, :spaces
245
261
  aliases 'no-multiple-space-closed-atx'
246
262
  check do |doc|
@@ -252,7 +268,7 @@ rule "MD021", "Multiple spaces inside hashes on closed atx style header" do
252
268
  end
253
269
  end
254
270
 
255
- rule "MD022", "Headers should be surrounded by blank lines" do
271
+ rule 'MD022', 'Headers should be surrounded by blank lines' do
256
272
  tags :headers, :blank_lines
257
273
  aliases 'blanks-around-headers'
258
274
  check do |doc|
@@ -261,13 +277,11 @@ rule "MD022", "Headers should be surrounded by blank lines" do
261
277
  header_bad = false
262
278
  linenum = doc.element_linenumber(h)
263
279
  # Check previous line
264
- if linenum > 1 and not doc.lines[linenum - 2].empty?
265
- header_bad = true
266
- end
280
+ header_bad = true if (linenum > 1) && !doc.lines[linenum - 2].empty?
267
281
  # Check next line
268
282
  next_line_idx = doc.header_style(h) == :setext ? linenum + 1 : linenum
269
283
  next_line = doc.lines[next_line_idx]
270
- header_bad = true if not next_line.nil? and not next_line.empty?
284
+ header_bad = true if !next_line.nil? && !next_line.empty?
271
285
  errors << linenum if header_bad
272
286
  end
273
287
  # Kramdown requires that headers start on a block boundary, so in most
@@ -275,16 +289,14 @@ rule "MD022", "Headers should be surrounded by blank lines" do
275
289
  # to check regular text and pick out headers ourselves too
276
290
  doc.find_type_elements(:p, false).each do |p|
277
291
  linenum = doc.element_linenumber(p)
278
- text = p.children.select { |e| e.type == :text }.map {|e| e.value }.join
292
+ text = p.children.select { |e| e.type == :text }.map(&:value).join
279
293
  lines = text.split("\n")
280
- prev_lines = ["", ""]
294
+ prev_lines = ['', '']
281
295
  lines.each do |line|
282
296
  # First look for ATX style headers without blank lines before
283
- if line.match(/^\#{1,6}/) and not prev_lines[1].empty?
284
- errors << linenum
285
- end
297
+ errors << linenum if line.match(/^\#{1,6}/) && !prev_lines[1].empty?
286
298
  # Next, look for setext style
287
- if line.match(/^(-+|=+)\s*$/) and not prev_lines[0].empty?
299
+ if line.match(/^(-+|=+)\s*$/) && !prev_lines[0].empty?
288
300
  errors << linenum - 1
289
301
  end
290
302
  linenum += 1
@@ -296,7 +308,7 @@ rule "MD022", "Headers should be surrounded by blank lines" do
296
308
  end
297
309
  end
298
310
 
299
- rule "MD023", "Headers must start at the beginning of the line" do
311
+ rule 'MD023', 'Headers must start at the beginning of the line' do
300
312
  tags :headers, :spaces
301
313
  aliases 'header-start-left'
302
314
  check do |doc|
@@ -311,14 +323,12 @@ rule "MD023", "Headers must start at the beginning of the line" do
311
323
  doc.find_type_elements(:p, false).each do |p|
312
324
  linenum = doc.element_linenumber(p)
313
325
  lines = doc.extract_text(p)
314
- prev_line = ""
326
+ prev_line = ''
315
327
  lines.each do |line|
316
328
  # First look for ATX style headers
317
- if line.match(/^\s+\#{1,6}/)
318
- errors << linenum
319
- end
329
+ errors << linenum if line.match(/^\s+\#{1,6}/)
320
330
  # Next, look for setext style
321
- if line.match(/^\s+(-+|=+)\s*$/) and not prev_line.empty?
331
+ if line.match(/^\s+(-+|=+)\s*$/) && !prev_line.empty?
322
332
  errors << linenum - 1
323
333
  end
324
334
  linenum += 1
@@ -329,7 +339,7 @@ rule "MD023", "Headers must start at the beginning of the line" do
329
339
  end
330
340
  end
331
341
 
332
- rule "MD024", "Multiple headers with the same content" do
342
+ rule 'MD024', 'Multiple headers with the same content' do
333
343
  tags :headers
334
344
  aliases 'no-duplicate-header'
335
345
  params :allow_different_nesting => false
@@ -357,8 +367,8 @@ rule "MD024", "Multiple headers with the same content" do
357
367
  stack.pop
358
368
  elsif current_level < level
359
369
  stack.push([text])
360
- else
361
- same_nesting_duplicates.add(header) if stack.last.include?(text)
370
+ elsif stack.last.include?(text)
371
+ same_nesting_duplicates.add(header)
362
372
  end
363
373
 
364
374
  current_level = level
@@ -371,30 +381,34 @@ rule "MD024", "Multiple headers with the same content" do
371
381
  end
372
382
  end
373
383
 
374
- rule "MD025", "Multiple top level headers in the same document" do
384
+ rule 'MD025', 'Multiple top level headers in the same document' do
375
385
  tags :headers
376
386
  aliases 'single-h1'
377
387
  params :level => 1
378
388
  check do |doc|
379
- headers = doc.find_type(:header, false).select { |h| h[:level] == params[:level] }
380
- if not headers.empty? and doc.element_linenumber(headers[0]) == 1
389
+ headers = doc.find_type(:header, false).select do |h|
390
+ h[:level] == params[:level]
391
+ end
392
+ if !headers.empty? && (doc.element_linenumber(headers[0]) == 1)
381
393
  headers[1..-1].map { |h| doc.element_linenumber(h) }
382
394
  end
383
395
  end
384
396
  end
385
397
 
386
- rule "MD026", "Trailing punctuation in header" do
398
+ rule 'MD026', 'Trailing punctuation in header' do
387
399
  tags :headers
388
400
  aliases 'no-trailing-punctuation'
389
401
  params :punctuation => '.,;:!?'
390
402
  check do |doc|
391
- doc.find_type(:header).select {
392
- |h| h[:raw_text].match(/[#{params[:punctuation]}]$/) }.map {
393
- |h| doc.element_linenumber(h) }
403
+ doc.find_type(:header).select do |h|
404
+ h[:raw_text].match(/[#{params[:punctuation]}]$/)
405
+ end.map do |h|
406
+ doc.element_linenumber(h)
407
+ end
394
408
  end
395
409
  end
396
410
 
397
- rule "MD027", "Multiple spaces after blockquote symbol" do
411
+ rule 'MD027', 'Multiple spaces after blockquote symbol' do
398
412
  tags :blockquote, :whitespace, :indentation
399
413
  aliases 'no-multiple-space-blockquote'
400
414
  check do |doc|
@@ -403,7 +417,7 @@ rule "MD027", "Multiple spaces after blockquote symbol" do
403
417
  linenum = doc.element_linenumber(e)
404
418
  lines = doc.extract_text(e, /^\s*> /)
405
419
  lines.each do |line|
406
- errors << linenum if line.start_with?(" ")
420
+ errors << linenum if line.start_with?(' ')
407
421
  linenum += 1
408
422
  end
409
423
  end
@@ -411,7 +425,7 @@ rule "MD027", "Multiple spaces after blockquote symbol" do
411
425
  end
412
426
  end
413
427
 
414
- rule "MD028", "Blank line inside blockquote" do
428
+ rule 'MD028', 'Blank line inside blockquote' do
415
429
  tags :blockquote, :whitespace
416
430
  aliases 'no-blanks-blockquote'
417
431
  check do |doc|
@@ -420,7 +434,7 @@ rule "MD028", "Blank line inside blockquote" do
420
434
  elements.each do |e|
421
435
  prev.shift
422
436
  prev << e.type
423
- if prev == [:blockquote, :blank, :blockquote]
437
+ if prev == %i{blockquote blank blockquote}
424
438
  # The current location is the start of the second blockquote, so the
425
439
  # line before will be a blank line in between the two, or at least the
426
440
  # lowest blank line if there are more than one.
@@ -435,42 +449,49 @@ rule "MD028", "Blank line inside blockquote" do
435
449
  end
436
450
  end
437
451
 
438
- rule "MD029", "Ordered list item prefix" do
452
+ rule 'MD029', 'Ordered list item prefix' do
439
453
  tags :ol
440
454
  aliases 'ol-prefix'
441
455
  # Style can be :one or :ordered
442
456
  params :style => :one
443
457
  check do |doc|
444
- if params[:style] == :ordered
445
- doc.find_type_elements(:ol).map { |l|
446
- doc.find_type_elements(:li, false, l.children).map.with_index { |i, idx|
447
- doc.element_linenumber(i) \
448
- unless doc.element_line(i).strip.start_with?("#{idx+1}. ")
449
- }
450
- }.flatten.compact
451
- elsif params[:style] == :one
452
- doc.find_type_elements(:ol).map { |l|
453
- doc.find_type_elements(:li, false, l.children) }.flatten.map { |i|
454
- doc.element_linenumber(i) \
455
- unless doc.element_line(i).strip.start_with?('1. ') }.compact
458
+ case params[:style]
459
+ when :ordered
460
+ doc.find_type_elements(:ol).map do |l|
461
+ doc.find_type_elements(:li, false, l.children)
462
+ .map.with_index do |i, idx|
463
+ unless doc.element_line(i).strip.start_with?("#{idx + 1}. ")
464
+ doc.element_linenumber(i)
465
+ end
466
+ end
467
+ end.flatten.compact
468
+ when :one
469
+ doc.find_type_elements(:ol).map do |l|
470
+ doc.find_type_elements(:li, false, l.children)
471
+ end.flatten.map do |i|
472
+ unless doc.element_line(i).strip.start_with?('1. ')
473
+ doc.element_linenumber(i)
474
+ end
475
+ end.compact
456
476
  end
457
477
  end
458
478
  end
459
479
 
460
- rule "MD030", "Spaces after list markers" do
480
+ rule 'MD030', 'Spaces after list markers' do
461
481
  tags :ol, :ul, :whitespace
462
482
  aliases 'list-marker-space'
463
483
  params :ul_single => 1, :ol_single => 1, :ul_multi => 1, :ol_multi => 1
464
484
  check do |doc|
465
485
  errors = []
466
- doc.find_type_elements([:ul, :ol]).each do |l|
486
+ doc.find_type_elements(%i{ul ol}).each do |l|
467
487
  list_type = l.type.to_s
468
488
  items = doc.find_type_elements(:li, false, l.children)
469
489
  # The entire list is to use the multi-paragraph spacing rule if any of
470
490
  # the items in it have multiple paragraphs/other block items.
471
- srule = items.map { |i| i.children.length }.max > 1 ? "multi" : "single"
491
+ srule = items.map { |i| i.children.length }.max > 1 ? 'multi' : 'single'
472
492
  items.each do |i|
473
- actual_spaces = doc.element_line(i).gsub(/^> /,'').match(/^\s*\S+(\s+)/)[1].length
493
+ actual_spaces = doc.element_line(i).gsub(/^> /, '')
494
+ .match(/^\s*\S+(\s+)/)[1].length
474
495
  required_spaces = params["#{list_type}_#{srule}".to_sym]
475
496
  errors << doc.element_linenumber(i) if required_spaces != actual_spaces
476
497
  end
@@ -479,7 +500,7 @@ rule "MD030", "Spaces after list markers" do
479
500
  end
480
501
  end
481
502
 
482
- rule "MD031", "Fenced code blocks should be surrounded by blank lines" do
503
+ rule 'MD031', 'Fenced code blocks should be surrounded by blank lines' do
483
504
  tags :code, :blank_lines
484
505
  aliases 'blanks-around-fences'
485
506
  check do |doc|
@@ -488,23 +509,29 @@ rule "MD031", "Fenced code blocks should be surrounded by blank lines" do
488
509
  # blocks without surrounding whitespace, so examine the lines directly.
489
510
  in_code = false
490
511
  fence = nil
491
- lines = [ "" ] + doc.lines + [ "" ]
512
+ lines = [''] + doc.lines + ['']
492
513
  lines.each_with_index do |line, linenum|
493
514
  line.strip.match(/^(`{3,}|~{3,})/)
494
- if $1 and (not in_code or $1.slice(0, fence.length) == fence)
495
- fence = in_code ? nil : $1
496
- in_code = !in_code
497
- if (in_code and not lines[linenum - 1].empty?) or
498
- (not in_code and not lines[linenum + 1].empty?)
499
- errors << linenum
500
- end
515
+ unless Regexp.last_match(1) &&
516
+ (
517
+ !in_code ||
518
+ (Regexp.last_match(1).slice(0, fence.length) == fence)
519
+ )
520
+ next
521
+ end
522
+
523
+ fence = in_code ? nil : Regexp.last_match(1)
524
+ in_code = !in_code
525
+ if (in_code && !lines[linenum - 1].empty?) ||
526
+ (!in_code && !lines[linenum + 1].empty?)
527
+ errors << linenum
501
528
  end
502
529
  end
503
530
  errors
504
531
  end
505
532
  end
506
533
 
507
- rule "MD032", "Lists should be surrounded by blank lines" do
534
+ rule 'MD032', 'Lists should be surrounded by blank lines' do
508
535
  tags :bullet, :ul, :ol, :blank_lines
509
536
  aliases 'blanks-around-lists'
510
537
  check do |doc|
@@ -514,21 +541,24 @@ rule "MD032", "Lists should be surrounded by blank lines" do
514
541
  in_list = false
515
542
  in_code = false
516
543
  fence = nil
517
- prev_line = ""
544
+ prev_line = ''
518
545
  doc.lines.each_with_index do |line, linenum|
519
546
  next if line.strip == '{:toc}'
520
- if not in_code
521
- list_marker = line.strip.match(/^([\*\+\-]|(\d+\.))\s/)
522
- if list_marker and not in_list and not prev_line.match(/^($|\s)/)
547
+
548
+ unless in_code
549
+ list_marker = line.strip.match(/^([*+\-]|(\d+\.))\s/)
550
+ if list_marker && !in_list && !prev_line.match(/^($|\s)/)
523
551
  errors << linenum + 1
524
- elsif not list_marker and in_list and not line.match(/^($|\s)/)
552
+ elsif !list_marker && in_list && !line.match(/^($|\s)/)
525
553
  errors << linenum
526
554
  end
527
555
  in_list = list_marker
528
556
  end
529
557
  line.strip.match(/^(`{3,}|~{3,})/)
530
- if $1 and (not in_code or $1.slice(0, fence.length) == fence)
531
- fence = in_code ? nil : $1
558
+ if Regexp.last_match(1) && (
559
+ !in_code || (Regexp.last_match(1).slice(0, fence.length) == fence)
560
+ )
561
+ fence = in_code ? nil : Regexp.last_match(1)
532
562
  in_code = !in_code
533
563
  in_list = false
534
564
  end
@@ -538,7 +568,7 @@ rule "MD032", "Lists should be surrounded by blank lines" do
538
568
  end
539
569
  end
540
570
 
541
- rule "MD033", "Inline HTML" do
571
+ rule 'MD033', 'Inline HTML' do
542
572
  tags :html
543
573
  aliases 'no-inline-html'
544
574
  check do |doc|
@@ -546,15 +576,15 @@ rule "MD033", "Inline HTML" do
546
576
  end
547
577
  end
548
578
 
549
- rule "MD034", "Bare URL used" do
579
+ rule 'MD034', 'Bare URL used' do
550
580
  tags :links, :url
551
581
  aliases 'no-bare-urls'
552
582
  check do |doc|
553
- doc.matching_text_element_lines(/https?:\/\//)
583
+ doc.matching_text_element_lines(%r{https?://})
554
584
  end
555
585
  end
556
586
 
557
- rule "MD035", "Horizontal rule style" do
587
+ rule 'MD035', 'Horizontal rule style' do
558
588
  tags :hr
559
589
  aliases 'hr-style'
560
590
  params :style => :consistent
@@ -563,17 +593,19 @@ rule "MD035", "Horizontal rule style" do
563
593
  if hrs.empty?
564
594
  []
565
595
  else
566
- if params[:style] == :consistent
567
- doc_style = doc.element_line(hrs[0])
568
- else
569
- doc_style = params[:style]
570
- end
571
- doc.element_linenumbers(hrs.select{|e| doc.element_line(e) != doc_style})
596
+ doc_style = if params[:style] == :consistent
597
+ doc.element_line(hrs[0])
598
+ else
599
+ params[:style]
600
+ end
601
+ doc.element_linenumbers(
602
+ hrs.reject { |e| doc.element_line(e) == doc_style },
603
+ )
572
604
  end
573
605
  end
574
606
  end
575
607
 
576
- rule "MD036", "Emphasis used instead of a header" do
608
+ rule 'MD036', 'Emphasis used instead of a header' do
577
609
  tags :headers, :emphasis
578
610
  aliases 'no-emphasis-as-header'
579
611
  params :punctuation => '.,;:!?'
@@ -583,18 +615,20 @@ rule "MD036", "Emphasis used instead of a header" do
583
615
  errors = []
584
616
  doc.find_type_elements(:p, false).each do |p|
585
617
  next if p.children.length > 1
586
- next unless [:em, :strong].include?(p.children[0].type)
587
- lines = doc.extract_text(p.children[0], "", false)
618
+ next unless %i{em strong}.include?(p.children[0].type)
619
+
620
+ lines = doc.extract_text(p.children[0], '', false)
588
621
  next if lines.length > 1
589
622
  next if lines.empty?
590
623
  next if lines[0].match(/[#{params[:punctuation]}]$/)
624
+
591
625
  errors << doc.element_linenumber(p)
592
626
  end
593
627
  errors
594
628
  end
595
629
  end
596
630
 
597
- rule "MD037", "Spaces inside emphasis markers" do
631
+ rule 'MD037', 'Spaces inside emphasis markers' do
598
632
  tags :whitespace, :emphasis
599
633
  aliases 'no-space-in-emphasis'
600
634
  check do |doc|
@@ -606,54 +640,59 @@ rule "MD037", "Spaces inside emphasis markers" do
606
640
  end
607
641
  end
608
642
 
609
- rule "MD038", "Spaces inside code span elements" do
643
+ rule 'MD038', 'Spaces inside code span elements' do
610
644
  tags :whitespace, :code
611
645
  aliases 'no-space-in-code'
612
646
  check do |doc|
613
647
  # We only want to check single line codespan elements and not fenced code
614
648
  # block that happen to be parsed as code spans.
615
- doc.element_linenumbers(doc.find_type_elements(:codespan).select{
616
- |i| i.value.match(/(^\s|\s$)/) and not i.value.include?("\n")})
649
+ doc.element_linenumbers(
650
+ doc.find_type_elements(:codespan).select do |i|
651
+ i.value.match(/(^\s|\s$)/) and !i.value.include?("\n")
652
+ end,
653
+ )
617
654
  end
618
655
  end
619
656
 
620
- rule "MD039", "Spaces inside link text" do
657
+ rule 'MD039', 'Spaces inside link text' do
621
658
  tags :whitespace, :links
622
659
  aliases 'no-space-in-links'
623
660
  check do |doc|
624
661
  doc.element_linenumbers(
625
- doc.find_type_elements(:a).reject{|e|e.children.empty?}.select{|e|
662
+ doc.find_type_elements(:a).reject { |e| e.children.empty? }.select do |e|
626
663
  e.children.first.type == :text && e.children.last.type == :text and (
627
- e.children.first.value.start_with?(" ") or
628
- e.children.last.value.end_with?(" "))}
664
+ e.children.first.value.start_with?(' ') or
665
+ e.children.last.value.end_with?(' '))
666
+ end,
629
667
  )
630
668
  end
631
669
  end
632
670
 
633
- rule "MD040", "Fenced code blocks should have a language specified" do
671
+ rule 'MD040', 'Fenced code blocks should have a language specified' do
634
672
  tags :code, :language
635
673
  aliases 'fenced-code-language'
636
674
  check do |doc|
637
675
  # Kramdown parses code blocks with language settings as code blocks with
638
676
  # the class attribute set to language-languagename.
639
- doc.element_linenumbers(doc.find_type_elements(:codeblock).select{|i|
640
- not i.attr['class'].to_s.start_with?("language-") and
641
- not doc.element_line(i).start_with?(" ")})
677
+ doc.element_linenumbers(doc.find_type_elements(:codeblock).select do |i|
678
+ !i.attr['class'].to_s.start_with?('language-') and
679
+ !doc.element_line(i).start_with?(' ')
680
+ end)
642
681
  end
643
682
  end
644
683
 
645
- rule "MD041", "First line in file should be a top level header" do
684
+ rule 'MD041', 'First line in file should be a top level header' do
646
685
  tags :headers
647
686
  aliases 'first-line-h1'
648
687
  params :level => 1
649
688
  check do |doc|
650
689
  first_header = doc.find_type(:header).first
651
- [1] if first_header.nil? or first_header[:location] != 1 \
652
- or first_header[:level] != params[:level]
690
+ [1] if first_header.nil? || (first_header[:location] != 1) \
691
+ || (first_header[:level] != params[:level])
653
692
  end
654
693
  end
655
694
 
656
- rule "MD046", "Code block style" do
695
+ rule 'MD046', 'Code block style' do
657
696
  tags :code
658
697
  aliases 'code-block-style'
659
698
  params :style => :fenced
@@ -663,11 +702,11 @@ rule "MD046", "Code block style" do
663
702
  doc.find_type_elements(:codeblock).select do |i|
664
703
  # for consistent we determine the first one
665
704
  if style == :consistent
666
- if doc.element_line(i).start_with?(" ")
667
- style = :indented
668
- else
669
- style = :fenced
670
- end
705
+ style = if doc.element_line(i).start_with?(' ')
706
+ :indented
707
+ else
708
+ :fenced
709
+ end
671
710
  end
672
711
  if style == :fenced
673
712
  # if our parent is a list or a codeblock, we need to ignore
@@ -677,7 +716,7 @@ rule "MD046", "Code block style" do
677
716
  if parent
678
717
  parent.options.delete(:children)
679
718
  parent.options.delete(:parent)
680
- if [:li, :codeblock].include?(parent.type)
719
+ if %i{li codeblock}.include?(parent.type)
681
720
  linenum = doc.element_linenumbers([parent]).first
682
721
  indent = doc.indent_for(doc.lines[linenum - 1])
683
722
  ignored_spaces = indent + 4
@@ -686,9 +725,9 @@ rule "MD046", "Code block style" do
686
725
  start = ' ' * ignored_spaces
687
726
  doc.element_line(i).start_with?("#{start} ")
688
727
  else
689
- !doc.element_line(i).start_with?(" ")
728
+ !doc.element_line(i).start_with?(' ')
690
729
  end
691
- end
730
+ end,
692
731
  )
693
732
  end
694
733
  end