<commit_before># Maybe the whole process should be a bunch of commands...
class LinkRelatedCardsCommand
  def initialize(cards)
    @cards = cards
  end

  def call
    @links = {}
    # Get longest match so
    # "Take Inventory" doesn't mistakenly seem to refer to "Take" etc.
    # Second regexp for empire series
    all_card_names = @cards.select{|name, card| card["layout"] != "token"}.keys
    any_card = Regexp.union(all_card_names.sort_by(&:size).reverse)
    rx = /\bnamed (#{any_card})(?:(?:,|,? and|,? or) (#{any_card}))?(?:(?:,|,? and|,? or) (#{any_card}))?/
    @cards.each do |name, card_data|
      matching_cards = (card_data["text"]||"").scan(rx).flatten.uniq - [name, nil]
      next if matching_cards.empty?
      matching_cards.each do |other|
        @links[name] ||= Set[]
        @links[name] << other
        @links[other] ||= Set[]
        @links[other] << name
      end
    end
    @links.each do |name, others|
      @cards[name]["related"] = others.sort
    end
  end
end
<commit_msg>Don't link Heart of Erises to Sacrifice or Unexpected Flood to Flood<commit_after># Maybe the whole process should be a bunch of commands...
class LinkRelatedCardsCommand
  def initialize(cards)
    @cards = cards
  end

  def call
    @links = {}
    # Get longest match so
    # "Take Inventory" doesn't mistakenly seem to refer to "Take" etc.
    # Second regexp for empire series
    all_card_names = @cards.select{|name, card| card["layout"] != "token"}.keys
    any_card = Regexp.union(all_card_names.sort_by(&:size).reverse)
    rx = /\bnamed (#{any_card})(?:(?:,|,? and|,? or) (#{any_card}))?(?:(?:,|,? and|,? or) (#{any_card}))?/
    @cards.each do |name, card_data|
      matching_cards = (card_data["text"]||"").scan(rx).flatten.uniq - [name, nil]
      next if matching_cards.empty?
      matching_cards.each do |other|
        # add specific exceptions for some false positives in custom cards
        next if name == "Heart of Erises" and other == "Sacrifice"
        next if name == "Unexpected Flood" and other == "Flood"
        @links[name] ||= Set[]
        @links[name] << other
        @links[other] ||= Set[]
        @links[other] << name
      end
    end
    @links.each do |name, others|
      @cards[name]["related"] = others.sort
    end
  end
end

{'fraction_non_alphanumeric': 0.1581476627348187, 'fraction_numerical': 0.0, 'mean_word_length': 3.0892857142857144, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3212831', 'n_tokens_mistral': 769, 'n_tokens_neox': 749, 'n_words': 216}