class RuboCop::Markdown::Preprocess

Transform source Markdown file into valid Ruby file by commenting out all non-code lines

Constants

MARKER
MD_REGEXP

This is a regexp to extract code blocks from .md files.

Only recognizes backticks-style code blocks.

Try it: rubular.com/r/iJaKBkSrrT

RUBY_TYPES

See github.com/github/linguist/blob/v5.3.3/lib/linguist/languages.yml#L3925

Attributes

config[R]

Public Class Methods

new(file) click to toggle source
# File lib/rubocop/markdown/preprocess.rb, line 65
def initialize(file)
  @config = Markdown.config_store.for(file)
end
restore!(file) click to toggle source

Revert preprocess changes.

When autocorrect is applied, RuboCop re-writes the file using preproccessed source buffer.

We have to restore it.

# File lib/rubocop/markdown/preprocess.rb, line 56
def restore!(file)
  contents = File.read(file)
  contents.gsub!(/^##{MARKER}/m, "")
  File.write(file, contents)
end

Public Instance Methods

call(src) click to toggle source

rubocop:disable Metrics/MethodLength

# File lib/rubocop/markdown/preprocess.rb, line 70
def call(src)
  parts = src.split(MD_REGEXP)

  walker = Walker.new

  parts.each do |part|
    if walker.code_body? && maybe_ruby?(@syntax) && valid_syntax?(@syntax, part)
      next walker.next!
    end

    if walker.code_attr?
      @syntax = part.gsub(/(^\s+|\s+$)/, "")
      next walker.next!
    end

    comment_lines! part

    walker.next!
  end

  parts.join
end

Private Instance Methods

autodetect?() click to toggle source

Whether to try to detect Ruby by parsing codeblock. If it's set to false we lint only implicitly specified Ruby blocks.

# File lib/rubocop/markdown/preprocess.rb, line 123
def autodetect?
  config["Markdown"]&.fetch("Autodetect", true)
end
comment_lines!(src) click to toggle source
# File lib/rubocop/markdown/preprocess.rb, line 127
def comment_lines!(src)
  return if src =~ /\A\n\z/

  src.gsub!(/^(.)/m, "##{MARKER}\\1")
end
maybe_ruby?(syntax) click to toggle source

Check codeblock attribute to prevent from parsing non-Ruby snippets and avoid false positives

# File lib/rubocop/markdown/preprocess.rb, line 98
def maybe_ruby?(syntax)
  (autodetect? && syntax.empty?) || ruby?(syntax)
end
ruby?(syntax) click to toggle source

Check codeblack attribute if it's defined and of Ruby type

# File lib/rubocop/markdown/preprocess.rb, line 103
def ruby?(syntax)
  RUBY_TYPES.include?(syntax)
end
valid_syntax?(syntax, src) click to toggle source

Try to parse with Ripper Invalid Ruby code (or non-Ruby) returns `nil`. Return true if it's explicit Ruby and warn_invalid?

# File lib/rubocop/markdown/preprocess.rb, line 110
def valid_syntax?(syntax, src)
  return true if ruby?(syntax) && warn_invalid?

  !Ripper.sexp(src).nil?
end
warn_invalid?() click to toggle source

Whether to show warning when snippet is not a valid Ruby

# File lib/rubocop/markdown/preprocess.rb, line 117
def warn_invalid?
  config["Markdown"]&.fetch("WarnInvalid", true)
end