Class: Hoe::Halostatue::Markdown::Linkify
- Inherits:
-
Object
- Object
- Hoe::Halostatue::Markdown::Linkify
- Defined in:
- lib/hoe/halostatue/markdown/linkify.rb
Overview
:nodoc:
Constant Summary collapse
- USERNAME_PATTERN =
Match GitHub username (@username) but not email addresses or Mastodon handles Basic pattern - additional validation done post-match
%r{ (?<![A-Za-z0-9]) # Not preceded by alphanumeric (prevents email match) @ # Literal @ sign ([A-Za-z0-9-]{1,39}) # 1-39 chars of alphanumeric or hyphen (?![-A-Za-z0-9@]) # Not followed by alphanumeric, hyphen, or @ (prevents Mastodon/email) }x
Class Method Summary collapse
- .linkify(source) ⇒ Object
- .linkify_file(filename) ⇒ Object
- .normalize_uri_prefixes(prefixes) ⇒ Object
Instance Method Summary collapse
-
#initialize(bug_tracker_uri: nil, style: :reference, uri_prefixes: {}) ⇒ Linkify
constructor
A new instance of Linkify.
- #linkify(source) ⇒ Object
Constructor Details
#initialize(bug_tracker_uri: nil, style: :reference, uri_prefixes: {}) ⇒ Linkify
Returns a new instance of Linkify.
48 49 50 51 52 53 |
# File 'lib/hoe/halostatue/markdown/linkify.rb', line 48 def initialize(bug_tracker_uri: nil, style: :reference, uri_prefixes: {}) @bug_tracker_uri = bug_tracker_uri @repo_owner, @repo_name = extract_repo_info(bug_tracker_uri) @style = style @uri_prefixes = self.class.normalize_uri_prefixes(uri_prefixes) end |
Class Method Details
.linkify(source) ⇒ Object
27 28 29 |
# File 'lib/hoe/halostatue/markdown/linkify.rb', line 27 def self.linkify(source, ...) new(...).linkify(source) end |
.linkify_file(filename) ⇒ Object
23 24 25 |
# File 'lib/hoe/halostatue/markdown/linkify.rb', line 23 def self.linkify_file(filename, ...) new(...).linkify(File.read(filename)) end |
.normalize_uri_prefixes(prefixes) ⇒ Object
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/hoe/halostatue/markdown/linkify.rb', line 31 def self.normalize_uri_prefixes(prefixes) case prefixes when true {issue: "issue", pull: "pull request", discussion: "discussion"} when false, nil {} else extra = prefixes.keys - %i[issue pull discussion] if extra.empty? prefixes else raise ArgumentError, "Extra keys for markdown_linkify_uri_prefixes: #{extra.inspect}" end end end |
Instance Method Details
#linkify(source) ⇒ Object
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
# File 'lib/hoe/halostatue/markdown/linkify.rb', line 55 def linkify(source) scan_existing_references(source) => {existing_by_key:, existing_by_ref:} new_by_key = {} new_by_ref = {} replacements = [] processed_positions = Set.new doc = Kramdown::Document.new(source, input: "GFM") walk(doc.root) do |element, ancestors| next unless element.type == :text next if in_skip_context?(ancestors) text = element.value # Find this text occurrence in source that we haven't processed yet source_offset = 0 while (text_pos = source.index(text, source_offset)) break if processed_positions.include?(text_pos) # Mark this position as processed processed_positions.add(text_pos) # Scan for patterns in this text occurrence scan_usernames(source, text, text_pos, replacements, existing_by_key, existing_by_ref, new_by_key, new_by_ref) scan_owner_repo_issues(source, text, text_pos, replacements, existing_by_key, existing_by_ref, new_by_key, new_by_ref) scan_issue_mentions(source, text, text_pos, replacements, existing_by_key, existing_by_ref, new_by_key, new_by_ref) scan_github_uris(source, text, text_pos, replacements, existing_by_key, existing_by_ref, new_by_key, new_by_ref) scan_github_repo_uris(source, text, text_pos, replacements, existing_by_key, existing_by_ref, new_by_key, new_by_ref) scan_github_user_uris(source, text, text_pos, replacements, existing_by_key, existing_by_ref, new_by_key, new_by_ref) break # Only process first unprocessed occurrence end end return {markdown: source, changed: false} if replacements.empty? # Apply replacements in reverse result = source.dup replacements.reverse_each do |r| result[r[:start]...r[:end]] = r[:replacement] end # Append new references if using reference style if @style == :reference && !new_by_key.empty? result = append_references(result, new_by_key) end {markdown: result, changed: true} end |