module MarkdownLint
Primary MDL container
Constants
- VERSION
Public Class Methods
Source
# File lib/mdl.rb, line 179 def self.linkify(text, url) return text unless $stdout.tty? && url "\e]8;;#{url}\e\\#{text}\e]8;;\e\\" end
Creates hyperlinks in terminal emulators, if available: gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda
Source
# File lib/mdl.rb, line 172 def self.printable_id(rule) return rule.aliases.first if Config[:show_aliases] && rule.aliases.any? rule.id end
Source
# File lib/mdl.rb, line 15 def self.run(argv = ARGV) cli = MarkdownLint::CLI.new cli.run(argv) ruleset = RuleSet.new ruleset.load_default unless Config[:skip_default_ruleset] Config[:rulesets]&.each do |r| ruleset.load(r) end rules = ruleset.rules Style.load(Config[:style], rules) # Rule option filter if Config[:rules] unless Config[:rules][:include].empty? rules.select! do |r, v| Config[:rules][:include].include?(r) or Config[:rules][:include].intersect?(v.aliases) end end unless Config[:rules][:exclude].empty? rules.select! do |r, v| !Config[:rules][:exclude].include?(r) and !Config[:rules][:exclude].intersect?(v.aliases) end end end # Tag option filter if Config[:tags] rules.select! { |_r, v| v.tags.intersect?(Config[:tags][:include]) } \ unless Config[:tags][:include].empty? rules.reject! { |_r, v| v.tags.intersect?(Config[:tags][:exclude]) } \ unless Config[:tags][:exclude].empty? end if Config[:list_rules] puts 'Enabled rules:' rules.each do |id, rule| if Config[:verbose] puts "#{id} (#{rule.aliases.join(', ')}) [#{rule.tags.join(', ')}] " + "- #{rule.description}" elsif Config[:show_aliases] puts "#{rule.aliases.first || id} - #{rule.description}" else puts "#{id} - #{rule.description}" end end exit 0 end # Recurse into directories cli.cli_arguments.each_with_index do |filename, i| filename = filename.chomp('/') if filename.end_with?('/') if Dir.exist?(filename) if Config[:git_recurse] Dir.chdir(filename) do cli.cli_arguments[i] = Mixlib::ShellOut.new("git ls-files '*.md' '*.markdown'") .run_command.stdout.lines .map { |m| File.join(filename, m.strip) } end else cli.cli_arguments[i] = Dir["#{filename}/**/*.{md,markdown}"] end end end cli.cli_arguments.flatten! status = 0 results = [] docs_to_print = [] cli.cli_arguments.each do |filename| puts "Checking #{filename}..." if Config[:verbose] unless filename == '-' || File.exist?(filename) warn( "#{Errno::ENOENT}: No such file or directory - #{filename}", ) exit 3 end if Config[:fix] && filename != '-' original_text = File.read(filename, :encoding => 'UTF-8').scrub text = original_text.dup end doc = Doc.new_from_file(filename, Config[:ignore_front_matter]) filename = '(stdin)' if filename == '-' if Config[:show_kramdown_warnings] status = 2 unless doc.parsed.warnings.empty? doc.parsed.warnings.each do |w| puts "#{filename}: Kramdown Warning: #{w}" end end rules.sort.each do |id, rule| puts "Processing rule #{id}" if Config[:verbose] error_lines = rule.check.call(doc) next if error_lines.nil? || error_lines.empty? status = 1 corrected = false if Config[:fix] && filename != '(stdin)' && rule.fix rule.fix.call(doc, error_lines) text = doc.to_s doc = Doc.new(text.dup, Config[:ignore_front_matter]) corrected = true end suffix = corrected ? ' (corrected)' : '' error_lines.each do |line| line += doc.offset # Correct line numbers for any yaml front matter if Config[:json] || Config[:sarif] result = { 'filename' => filename, 'line' => line, 'rule' => id, 'aliases' => rule.aliases, 'description' => rule.description, 'docs' => rule.docs_url, } result['corrected'] = corrected if Config[:fix] results << result else linked_id = linkify(printable_id(rule), rule.docs_url) puts "#{filename}:#{line}: #{linked_id} " \ "#{rule.description}#{suffix}" end end # If we're not in JSON or SARIF mode (URLs are in the object), and we # cannot make real links (checking if we have a TTY is an OK heuristic # for that) then, instead of making the output ugly with long URLs, we # print them at the end. And of course we only want to print each URL # once. next unless !Config[:json] && !Config[:sarif] && !$stdout.tty? && rule.docs_url && !docs_to_print.include?(rule) docs_to_print << rule end if Config[:fix] && filename != '(stdin)' && text != original_text File.write(filename, text) end end if Config[:json] require 'json' puts JSON.generate(results) elsif Config[:sarif] puts SarifFormatter.generate(rules, results) elsif docs_to_print.any? puts "\nFurther documentation is available for these failures:" docs_to_print.each do |rule| puts " - #{printable_id(rule)}: #{rule.docs_url}" end end exit status end