<commit_before>module HtmlFormatting
  protected
  
  include ActionView::Helpers::UrlHelper
  
  def format_attributes
    self.class.formatted_attributes.each do |attr|
      raw = read_attribute attr

      text = format_textile(raw)
      text = format_usernames(text)
      text = format_links(text)
      
      write_attribute "#{attr}_html", white_list_sanitizer.sanitize(text)
    end
  end
  
  # Get @username, like in Twitter, and link it to user path
  def format_usernames(text)
    text.gsub(/([\s>])@([a-z0-9_]+)([\W])/i) do |match|
      user = User.find_by_login(match[2..-2])
      if user && is_in_project?(user)
        if is_a? Comment
          @mentioned ||= []
          @mentioned |= [user]
        end
        match[0,2] + link_to(user.login, "/users/#{user.login}") + match[-1,1]
      else
        match
      end
    end
  end
  
  def is_in_project?(user)
     Person.exists?(:user_id => user.id, :project_id => project.id)
  end
  <commit_msg>Silently fail formatting attributes with nil values<commit_after>module HtmlFormatting
  protected
  
  include ActionView::Helpers::UrlHelper
  
  def format_attributes
    self.class.formatted_attributes.each do |attr|
      raw = read_attribute attr

      text = format_textile(raw || '')
      text = format_usernames(text)
      text = format_links(text)
      
      write_attribute "#{attr}_html", white_list_sanitizer.sanitize(text)
    end
  end
  
  # Get @username, like in Twitter, and link it to user path
  def format_usernames(text)
    text.gsub(/([\s>])@([a-z0-9_]+)([\W])/i) do |match|
      user = User.find_by_login(match[2..-2])
      if user && is_in_project?(user)
        if is_a? Comment
          @mentioned ||= []
          @mentioned |= [user]
        end
        match[0,2] + link_to(user.login, "/users/#{user.login}") + match[-1,1]
      else
        match
      end
    end
  end
  
  def is_in_project?(user)
     Person.exists?(:user_id => user.id, :project_id => project.id)
  end
  
{'fraction_non_alphanumeric': 0.1283851554663992, 'fraction_numerical': 0.00802407221664995, 'mean_word_length': 2.607594936708861, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 9, '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': '6502013', 'n_tokens_mistral': 686, 'n_tokens_neox': 688, 'n_words': 142}