<commit_before>module PagesCore
	module ActsAsTextable
	
		class << self
			def textable_fields
				@@textable_fields  ||= {}
			end
			
			def textable_options
				@@textable_options ||= {}
			end
		end

		# Model for <tt>acts_as_textable</tt>
		module Model
			# Class methods for <tt>acts_as_textable</tt> models
			module ClassMethods
				def languages(options={})
					options = {:type => self.to_s}.merge(options)
					Textbit.languages(options)
				end
				def fields( options={} )
					options = {:type => self.to_s}.merge(options)
					Textbit.fields( options )
				end
				def textable_options
					PagesCore::ActsAsTextable.textable_options[self] || {}
				end
			end
			
			def root_class
				rc = self.class
				while rc.superclass != ActiveRecord::Base
					rc = rc.superclass
				end
				rc
			end
			
			# Set the working language
			def working_language=(language)
				@working_language = language.to_s
			end

			# Get the working language
			def working_language
				@working_language ||= Language.default
			end

			# Set the fallback language
			def fallback_language=(language)
				@fallback_language = language.to_s
			end

			# Get the fallback language
			def fallback_language
				@fallback_language || self.root_class.textable_options[:fallback_language]
			end
			
			# Does this model have a fallback language?
			def fallback_language?
				self.fallback_language ? true : false
			end

			def attributes=(new_attributes, guard_protected_attributes=true)
				attributes = new_attributes.dup
				attributes.stringify_keys!
				attributes = remove_attributes_protected_from_mass_assignment(attributes) if guard_protected_attributes
				attributes.each do |attribute, value|
					if self.has_field?(attribute)
						attributes.delete(attribute)
						set_textbit_body(attribute, value)
					end
				end
				super(attributes, guard_protected_attributes)
			end

			# Returns true if this page has the named textbit
			def has_field?(name, options={})
				return true if (PagesCore::ActsAsTextable.textable_fields[self.root_class].include?(name))
				(self.fields.include?(name.to_s)) ? true : false
			end

			# Get the textbit with specified name (and optional language), create and add it if necessary
			def get_textbit(name, options={})
				name = name.to_s
				
				languages      = options[:language] ? [options[:language]] : [self.working_language, self.fallback_language].compact
				named_textbits = self.textbits.select{|tb| tb.name == name}
				textbit        = nil
				
				# Find the first applicable textbit
				languages.each do |lang|
					if !textbit && named_textbits.select{|tb| tb.language == lang.to_s}.length > 0
						textbit = named_textbits.select{|tb| tb.language == lang.to_s}.first
					end
				end

				# Default to a blank one
				textbit ||= Textbit.new(:name => name, :textable => self, :language => languages.first)
				self.textbits.push(textbit) if textbit.new_record?

				textbit
			end

			# Set the body of a named textbit (usually, through method_missing)
			def set_textbit_body( name, value, options={} )
				if value.kind_of? Hash
					value.each do |language,string|
						set_textbit_body( name, string, options.merge( { :language => language } ) )
					end
				else
					textbit = get_textbit( name, options )
					textbit.body = value
				end
			end


			# Save all related textbits
			def save_textbits
				self.textbits.each do |tb|
					tb.save
				end
			end

			# Returns an array of all language codes present on this page.
			def languages
				self.textbits.collect {|tb| tb.language }.uniq.compact
			end

			# Returns an array of language codes this field is translated into.<commit_msg>Compensate for magic with more magic<commit_after>module PagesCore
	module ActsAsTextable
	
		class << self
			def textable_fields
				@@textable_fields  ||= {}
			end
			
			def textable_options
				@@textable_options ||= {}
			end
		end

		# Model for <tt>acts_as_textable</tt>
		module Model
			# Class methods for <tt>acts_as_textable</tt> models
			module ClassMethods
				def languages(options={})
					options = {:type => self.to_s}.merge(options)
					Textbit.languages(options)
				end
				def fields( options={} )
					options = {:type => self.to_s}.merge(options)
					Textbit.fields( options )
				end
				def textable_options
					PagesCore::ActsAsTextable.textable_options[self] || {}
				end
			end
			
			def root_class
				rc = self.class
				while rc.superclass != ActiveRecord::Base
					rc = rc.superclass
				end
				rc
			end
			
			# Set the working language
			def working_language=(language)
				@working_language = language.to_s
			end

			# Get the working language
			def working_language
				@working_language ||= Language.default
			end

			# Set the fallback language
			def fallback_language=(language)
				@fallback_language = language.to_s
			end

			# Get the fallback language
			def fallback_language
				@fallback_language || self.root_class.textable_options[:fallback_language]
			end
			
			# Does this model have a fallback language?
			def fallback_language?
				self.fallback_language ? true : false
			end

			def attributes=(new_attributes, guard_protected_attributes=true)
				attributes = new_attributes.dup
				attributes.stringify_keys!
				attributes = remove_attributes_protected_from_mass_assignment(attributes) if guard_protected_attributes
				attributes.each do |attribute, value|
					if self.has_field?(attribute)
						attributes.delete(attribute)
						set_textbit_body(attribute, value)
					end
				end
				super(attributes, guard_protected_attributes)
			end

			# Returns true if this page has the named textbit
			def has_field?(name, options={})
				return true if (PagesCore::ActsAsTextable.textable_fields[self.root_class].include?(name))
				(self.fields.include?(name.to_s)) ? true : false
			end

			# Get the textbit with specified name (and optional language), create and add it if necessary
			def get_textbit(name, options={})
				name = name.to_s
				
				languages      = options[:language] ? [options[:language]] : [self.working_language, self.fallback_language].compact
				named_textbits = self.textbits.select{|tb| tb.name == name}
				textbit        = nil
				
				# Find the first applicable textbit
				languages.each do |lang|
					if !textbit && named_textbits.select{|tb| tb.language == lang.to_s}.length > 0
						textbit = named_textbits.select{|tb| tb.language == lang.to_s}.first
					end
				end

				# Default to a blank one
				textbit ||= Textbit.new(:name => name, :textable => self, :language => languages.first)
				self.textbits.push(textbit) if textbit.new_record?

				textbit
			end

			# Set the body of a named textbit (usually, through method_missing)
			def set_textbit_body( name, value, options={} )
				if value.kind_of? Hash
					value.each do |language,string|
						set_textbit_body( name, string, options.merge( { :language => language } ) )
					end
				else
					options = {:language => self.working_language}.merge(options)
					textbit = get_textbit( name, options )
					textbit.body = value
				end
			end


			# Save all related textbits
			def save_textbits
				self.textbits.each do |tb|
					tb.save
				end
			end

			# Returns an array of all language codes present on this page.
			def languages
				self.textbits.collect {|tb| tb.language }.uniq.compact
			end

			# Returns an array of language codes this field is translated into.
{'fraction_non_alphanumeric': 0.08941556692701319, 'fraction_numerical': 0.00026932399676811203, 'mean_word_length': 3.1538031319910513, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 26, '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': '2251092', 'n_tokens_mistral': 2905, 'n_tokens_neox': 2229, 'n_words': 605}