<commit_before>module OpenStax
  module Api
    class RepresentableSchemaPrinter

      # Returns the json schema for a representer
      def self.json_schema(representer, options = {})
        definitions = {}
        schema = json_object(representer, definitions, options)
        schema[:definitions] = definitions unless definitions.blank?
        schema
      end

      # Returns some formatted Markdown with HTML containing the
      # JSON schema for a given representer
      def self.json(representer, options={})
        options[:include] ||= [:readable, :writeable]

        schema = json_schema(representer, options)

        json_string = JSON.pretty_generate(schema)

        "\n## Schema  {##{SecureRandom.hex(4)} .schema}\n" +
        "\n<pre class='code'>\n#{json_string}\n</pre>\n"
      end

      protected

      # Attempts to extract the given representer's name
      def self.representer_name(representer)
        name = representer.try :name
        return nil if name.nil?
        name.chomp('Representer').demodulize.camelize(:lower)
      end

      # Gets the definition name for the given representer name
      def self.definition_name(name)
        "#/definitions/#{name}"
      end

      # Helper function for json_schema
      def self.json_object(representer, definitions, options = {})
        # Initialize the schema
        schema = { type: :object, required: [], properties: {}, additionalProperties: false }

        representer.representable_attrs.each do |attr|
          # Handle some common attributes (as, schema_info, required)
          name = attr[:as].blank? ? attr[:name] : attr[:as].evaluate(representer) rescue attr[:name]
          schema_info = attr[:schema_info] || {}

          schema[:required].push(name.to_sym) if schema_info[:required]

          # Skip attr if it does not have the the specified key set to false
          # or it is explicitly "required"
          next unless [options[:include]].flatten.any? do |inc|
            m = inc.to_s + "?"
            (attr.respond_to?(m) ? attr.send(m) : attr[inc]) != false
          end || schema_info[:required]

          # Guess a default type based on the attribute name
          type = attr[:type].blank? ? (name.end_with?('id') ? :integer : :string) :
                                      attr[:type].to_s.downcase
          attr_info ||= { type: type }

          # Process the schema_info attribute
          schema_info.each do |key, value|
            # Handle special keys (required, definitions, type, enum)
            case key
            when :required
              next
            when :definitions
              definitions.merge!(value)
              next<commit_msg>handle  changes between representable and roar<commit_after>module OpenStax
  module Api
    class RepresentableSchemaPrinter

      # Returns the json schema for a representer
      def self.json_schema(representer, options = {})
        definitions = {}
        schema = json_object(representer, definitions, options)
        schema[:definitions] = definitions unless definitions.blank?
        schema
      end

      # Returns some formatted Markdown with HTML containing the
      # JSON schema for a given representer
      def self.json(representer, options={})
        options[:include] ||= [:readable, :writeable]

        schema = json_schema(representer, options)

        json_string = JSON.pretty_generate(schema)

        "\n## Schema  {##{SecureRandom.hex(4)} .schema}\n" +
        "\n<pre class='code'>\n#{json_string}\n</pre>\n"
      end

      protected

      # Attempts to extract the given representer's name
      def self.representer_name(representer)
        name = representer.try :name
        return nil if name.nil?
        name.chomp('Representer').demodulize.camelize(:lower)
      end

      # Gets the definition name for the given representer name
      def self.definition_name(name)
        "#/definitions/#{name}"
      end

      # Helper function for json_schema
      def self.json_object(representer, definitions, options = {})
        # Initialize the schema
        schema = { type: :object, required: [], properties: {}, additionalProperties: false }

        representer.representable_attrs.each do |attr|
          # Handle some common attributes (as, schema_info, required)
          name = attr[:as].blank? ?
                   attr[:name] :
                   attr[:as].evaluate(representer) rescue attr[:as].call rescue attr[:name]
          schema_info = attr[:schema_info] || {}

          schema[:required].push(name.to_sym) if schema_info[:required]

          # Skip attr if it does not have the the specified key set to false
          # or it is explicitly "required"
          next unless [options[:include]].flatten.any? do |inc|
            m = inc.to_s + "?"
            (attr.respond_to?(m) ? attr.send(m) : attr[inc]) != false
          end || schema_info[:required]

          # Guess a default type based on the attribute name
          type = attr[:type].blank? ? (name.end_with?('id') ? :integer : :string) :
                                      attr[:type].to_s.downcase
          attr_info ||= { type: type }

          # Process the schema_info attribute
          schema_info.each do |key, value|
            # Handle special keys (required, definitions, type, enum)
            case key
            when :required
              next
            when :definitions
              definitions.merge!(value)
              next
{'fraction_non_alphanumeric': 0.10263876251137398, 'fraction_numerical': 0.0003639672429481347, 'mean_word_length': 2.24822695035461, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1684331', 'n_tokens_mistral': 1489, 'n_tokens_neox': 1439, 'n_words': 414}