Module: Kettle::Dev::PreReleaseCLI::Markdown

Defined in:
lib/kettle/dev/pre_release_cli.rb

Overview

Markdown parsing helpers

Constant Summary collapse

SCRATCH_PATH_PREFIXES =
%w[
  tmp/
  .git/
].freeze

Class Method Summary collapse

Class Method Details

.extract_image_urls_from_files(glob_pattern = nil) ⇒ Array<String>

Extract from files matching glob.

Parameters:

  • glob_pattern (String, Array<String>) (defaults to: nil)

Returns:

  • (Array<String>)


162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
# File 'lib/kettle/dev/pre_release_cli.rb', line 162

def extract_image_urls_from_files(glob_pattern = nil)
  files =
    if glob_pattern.nil?
      project_markdown_files
    elsif glob_pattern.is_a?(String)
      Dir.glob(glob_pattern)
    else
      Array(glob_pattern)
    end
  urls = files.flat_map do |f|
    begin
      extract_image_urls_from_text(File.read(f))
    rescue => e
      warn("[kettle-pre-release] Could not read #{Kettle::Dev.display_path(f)}: #{e.class}: #{e.message}")
      []
    end
  end
  urls.uniq
end

.extract_image_urls_from_text(text) ⇒ Array<String>

Extract unique remote HTTP(S) image URLs from markdown or HTML images.

Parameters:

  • text (String)

Returns:

  • (Array<String>)


108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
# File 'lib/kettle/dev/pre_release_cli.rb', line 108

def extract_image_urls_from_text(text)
  urls = []

  # Inline image syntax
  text.scan(/!\[[^\]]*\]\(([^\s)]+)(?:\s+"[^"]*")?\)/) { |m| urls << m[0] }

  # Reference definitions
  ref_defs = {}
  text.scan(/^\s*\[([^\]]+)\]:\s*(\S+)/) { |m| ref_defs[m[0]] = m[1] }

  # Reference image usage
  text.scan(/!\[[^\]]*\]\[([^\]]+)\]/) do |m|
    id = m[0]
    url = ref_defs[id]
    urls << url if url
  end

  # HTML <img src="...">
  text.scan(/<img\b[^>]*\bsrc\s*=\s*"([^"]+)"[^>]*>/i) { |m| urls << m[0] }
  text.scan(/<img\b[^>]*\bsrc\s*=\s*'([^']+)'[^>]*>/i) { |m| urls << m[0] }

  urls.reject! { |u| u.nil? || u.strip.empty? }
  urls.select! { |u| u =~ %r{^https?://}i }
  urls.uniq
end

.project_markdown_filesArray<String>

Find Markdown files that are part of the releasable project.

Returns:

  • (Array<String>)


136
137
138
139
140
141
# File 'lib/kettle/dev/pre_release_cli.rb', line 136

def project_markdown_files
  files = tracked_markdown_files
  return files unless files.empty?

  Dir.glob(["**/*.md", "**/*.md.example"], File::FNM_DOTMATCH).reject { |path| scratch_path?(path) }.sort
end

.scratch_path?(path) ⇒ Boolean

Parameters:

  • path (String)

Returns:

  • (Boolean)


155
156
157
# File 'lib/kettle/dev/pre_release_cli.rb', line 155

def scratch_path?(path)
  SCRATCH_PATH_PREFIXES.any? { |prefix| path.start_with?(prefix) }
end

.tracked_markdown_filesArray<String>

Returns:

  • (Array<String>)


144
145
146
147
148
149
150
151
# File 'lib/kettle/dev/pre_release_cli.rb', line 144

def tracked_markdown_files
  output = IO.popen(["git", "ls-files", "-z", "--", "*.md", "*.md.example"], err: File::NULL, &:read)
  return [] unless $CHILD_STATUS.success?

  output.split("\0").reject { |path| scratch_path?(path) }.sort
rescue Errno::ENOENT
  []
end