Module: YARD::Markdown::LinkNormalizationHelper

Defined in:
lib/yard/markdown/link_normalization_helper.rb

Overview

Rewrites generated Markdown links so they point at Markdown output.

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.constant_reference_path?(value) ⇒ Boolean

Returns whether a path looks like a constant reference.

Parameters:

  • value (String)

    Link target to inspect.

Returns:

  • (Boolean)

    True when the path resembles a constant name.



83
84
85
86
87
88
# File 'lib/yard/markdown/link_normalization_helper.rb', line 83

def self.constant_reference_path?(value)
  parts = value.split(%r{::|/}).reject(&:empty?)
  return false if parts.empty?

  parts.all? { |part| part.match?(/\A[A-Z]\w*\z/) }
end

.finish_markdown(markdown) ⇒ String

Compacts blank lines and adds the final newline.

Parameters:

  • markdown (String)

    Normalized Markdown content.

Returns:

  • (String)

    Final Markdown content.



126
127
128
# File 'lib/yard/markdown/link_normalization_helper.rb', line 126

def self.finish_markdown(markdown)
  "#{markdown.gsub(/\n{3,}/, "\n\n").strip}\n"
end

.markdown_path(path) ⇒ String?

Returns the Markdown output path for a non-registry target.

Parameters:

  • path (String)

    Local link target.

Returns:

  • (String, nil)

    Markdown path, or nil for an unresolved identifier.



134
135
136
137
138
139
140
# File 'lib/yard/markdown/link_normalization_helper.rb', line 134

def self.markdown_path(path)
  return path.sub(/\.html\z/i, ".md") if path.match?(/\.html\z/i)
  return path unless File.extname(path).empty?
  return if unresolved_identifier_target?(path)

  "#{path}.md"
end

.normalize_lines(content) ⇒ String

Converts supported content into normalized lines.

Parameters:

  • content (String, Array<String>)

    Markdown content.

Returns:

  • (String)

    Joined content without trailing line whitespace.



117
118
119
120
# File 'lib/yard/markdown/link_normalization_helper.rb', line 117

def self.normalize_lines(content)
  text = content.instance_of?(Array) ? content.join("\n") : content
  text.lines.map(&:rstrip).join("\n")
end

.relative_output_path(current_dir, target_path) ⇒ String

Computes a relative path from the current output directory.

Parameters:

  • current_dir (Pathname)

    Directory for the current output file.

  • target_path (String, Pathname)

    Output path being linked to.

Returns:

  • (String)

    Relative path suitable for a Markdown link.



104
105
106
107
108
109
110
111
# File 'lib/yard/markdown/link_normalization_helper.rb', line 104

def self.relative_output_path(current_dir, target_path)
  target = target_path.to_s
  return target if target.start_with?("../")

  Pathname.new(target).relative_path_from(current_dir).to_s
rescue
  target
end

.resolve_registry_object(path, current_dir) ⇒ YARD::CodeObjects::Base?

Resolves a local link path to a YARD registry object when possible.

Parameters:

  • path (String)

    Link target path to resolve.

  • current_dir (Pathname)

    Directory for the current output file.

Returns:

  • (YARD::CodeObjects::Base, nil)

    Matched registry object, if any.



36
37
38
39
40
41
42
# File 'lib/yard/markdown/link_normalization_helper.rb', line 36

def self.resolve_registry_object(path, current_dir)
  registry_candidates(path, current_dir)
    .map { |candidate| Registry.at(candidate) }
    .compact
    .reject { |object| object.equal?(Registry.root) }
    .first
end

.unresolved_identifier_target?(path) ⇒ Boolean

Returns whether a path looks like an unresolved bare identifier.

Parameters:

  • path (String)

    Link target to inspect.

Returns:

  • (Boolean)

    True when the target should be treated as unresolved.



94
95
96
97
# File 'lib/yard/markdown/link_normalization_helper.rb', line 94

def self.unresolved_identifier_target?(path)
  cleaned = path.sub(%r{\A(?:(?:\.\./)+|\./)}, "")
  File.extname(cleaned).empty? && !cleaned.include?("/")
end

Instance Method Details

#finalize_markdown(content, current_path) ⇒ String

Normalizes generated Markdown before it is written to disk.

Parameters:

  • content (String, Array<String>)

    Markdown content to finalize.

  • current_path (String)

    Output path for the current document.

Returns:

  • (String)

    Normalized Markdown content with a trailing newline.



12
13
14
15
16
# File 'lib/yard/markdown/link_normalization_helper.rb', line 12

def finalize_markdown(content, current_path)
  LinkNormalizationHelper.finish_markdown(
    normalize_local_links(LinkNormalizationHelper.normalize_lines(content), current_path)
  )
end

Rewrites local Markdown links relative to the current output path.

Parameters:

  • markdown (String)

    Markdown content to rewrite.

  • current_path (String)

    Output path for the current document.

Returns:

  • (String)

    Markdown with local links normalized.



23
24
25
26
27
28
29
# File 'lib/yard/markdown/link_normalization_helper.rb', line 23

def normalize_local_links(markdown, current_path)
  current_dir = Pathname.new(current_path).dirname

  markdown.gsub(%r{\[(.+?)\]\((?!https?://|mailto:|#)([^)\n]+)\)}) do
    normalize_local_link(Regexp.last_match, current_dir)
  end
end

Resolves a local link target to the final relative Markdown path.

Parameters:

  • path (String)

    Link target path to resolve.

  • current_dir (Pathname)

    Directory for the current output file.

Returns:

  • (String, nil)

    Relative Markdown path, or nil when unresolved.



73
74
75
76
77
# File 'lib/yard/markdown/link_normalization_helper.rb', line 73

def resolve_local_link_target(path, current_dir)
  normalized = path.sub(%r{\A/+}, "")
  target = registry_path(normalized, current_dir) || copied_path(normalized) || LinkNormalizationHelper.markdown_path(normalized)
  LinkNormalizationHelper.relative_output_path(current_dir, target) if target
end