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

Defined in:
lib/kettle/dev/pre_release_cli.rb,
sig/kettle/dev.rbs

Overview

Markdown parsing helpers

Constant Summary collapse

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

Class Method Summary collapse

Class Method Details

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

Extract from files matching glob.



259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
# File 'lib/kettle/dev/pre_release_cli.rb', line 259

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.



205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
# File 'lib/kettle/dev/pre_release_cli.rb', line 205

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.



233
234
235
236
237
238
# File 'lib/kettle/dev/pre_release_cli.rb', line 233

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



252
253
254
# File 'lib/kettle/dev/pre_release_cli.rb', line 252

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

.tracked_markdown_filesArray<String>



241
242
243
244
245
246
247
248
# File 'lib/kettle/dev/pre_release_cli.rb', line 241

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