Class: Mdlint::Linter::DirectiveFilter

Inherits:
Object
  • Object
show all
Defined in:
lib/mdlint/linter/directive_filter.rb,
sig/internal.rbs

Constant Summary collapse

DIRECTIVE_REGEXP =
/<!--\s*mdlint-(disable-next-line|disable-file|disable|enable)(?:\s+([^>]*?))?\s*-->/i
FENCE_REGEXP =
/\A {0,3}(`{3,}|~{3,})/

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(source) ⇒ DirectiveFilter

Returns a new instance of DirectiveFilter.

Parameters:

  • source (Object)


17
18
19
20
21
# File 'lib/mdlint/linter/directive_filter.rb', line 17

def initialize(source)
  @disabled_by_line = {}
  @file_disabled = false
  scan(source)
end

Class Method Details

.apply(violations, source) ⇒ Object

Parameters:

  • violations (Object)
  • source (Object)

Returns:

  • (Object)


12
13
14
# File 'lib/mdlint/linter/directive_filter.rb', line 12

def apply(violations, source)
  new(source).filter(violations)
end

Instance Method Details

#apply_directive(directive, disabled, next_line, line_number) ⇒ Object

Parameters:

  • directive (Object)
  • disabled (Object)
  • next_line (Object)
  • line_number (Object)

Returns:

  • (Object)


66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/mdlint/linter/directive_filter.rb', line 66

def apply_directive(directive, disabled, next_line, line_number)
  action = directive[1].downcase
  ids = normalize_ids(directive[2])

  case action
  when "disable-file"
    @file_disabled = true
  when "disable-next-line"
    next_line[line_number + 1] ||= Set.new
    next_line[line_number + 1].merge(ids)
  when "disable"
    disabled.merge(ids)
  when "enable"
    ids.include?("*") ? disabled.clear : ids.each { |id| disabled.delete(id) }
  end
end

#filter(violations) ⇒ Object

Parameters:

  • violations (Object)

Returns:

  • (Object)


23
24
25
26
27
28
29
30
# File 'lib/mdlint/linter/directive_filter.rb', line 23

def filter(violations)
  return [] if @file_disabled

  violations.reject do |violation|
    disabled = @disabled_by_line.fetch(violation.line, Set.new)
    disabled.include?("*") || disabled.include?(RuleRegistry.normalize_id(violation.rule_id))
  end
end

#normalize_ids(value) ⇒ Object

Parameters:

  • value (Object)

Returns:

  • (Object)


83
84
85
86
87
88
# File 'lib/mdlint/linter/directive_filter.rb', line 83

def normalize_ids(value)
  ids = value.to_s.split(/[\s,]+/).reject(&:empty?)
  return Set["*"] if ids.empty?

  Set.new(ids.map { |id| RuleRegistry.normalize_id(id) })
end

#scan(source) ⇒ Object

Parameters:

  • source (Object)

Returns:

  • (Object)


34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/mdlint/linter/directive_filter.rb', line 34

def scan(source)
  disabled = Set.new
  next_line = {}
  fence = nil

  source.each_line.with_index(1) do |line, line_number|
    current_fence = line.match(FENCE_REGEXP)
    if current_fence
      marker = current_fence[1].to_s

      if !fence.nil? && marker.to_s[0] == fence.to_s[0] && marker.to_s.length >= fence.to_s.length
        fence = nil
      elsif fence.nil?
        fence = marker
      end
      @disabled_by_line[line_number] = disabled.dup
      next
    end

    if fence
      @disabled_by_line[line_number] = disabled.dup
      next
    end

    directive = line.match(DIRECTIVE_REGEXP)
    apply_directive(directive, disabled, next_line, line_number) if directive
    line_disabled = disabled.dup
    line_disabled.merge(next_line.delete(line_number) || Set.new)
    @disabled_by_line[line_number] = line_disabled
  end
end