<commit_before>module Pagination
  # = Pagination view helpers
  #
  # The main view helper, #paginate, renders
  # pagination links around (top and bottom) given collection. The helper itself is lightweight
  # and serves only as a wrapper around LinkRenderer instantiation; the
  # renderer then does all the hard work of generating the HTML.
  #
  # == Global options for helpers
  #
  # Options for pagination helpers are optional and get their default values from the
  # <tt>Pagination::ViewHelpers.pagination_options</tt> hash. You can write to this hash to
  # override default options on the global level:
  #
  #   Pagination::ViewHelpers.pagination_options[:previous_label] = 'Previous page'
  #
  # By putting this into "config/initializers/pagination.rb" (or simply environment.rb in
  # older versions of Rails) you can easily translate link texts to previous
  # and next pages, as well as override some other defaults to your liking.
  module ViewHelpers
    # default options that can be overridden on the global level
    @@pagination_options = {
      :class          => 'pagination',
      :previous_label => '&laquo; Previous',
      :next_label     => 'Next &raquo;',
      :inner_window   => 4, # links around the current page
      :outer_window   => 1, # links around beginning and end
      :separator      => ' ', # single space is friendly to spiders and non-graphic browsers
      :controls       => :both,
      :per_page       => 10,
      :param_name     => :page,
      :params         => nil,
      :renderer       => 'Pagination::LinkRenderer',
      :page_links     => true,
      :container      => true
    }
    mattr_reader :pagination_options

    # Renders Digg/Flickr-style pagination for a Pagination::Collection
    # object. Nil is returned if there is only one page in total; no point in
    # rendering the pagination in that case...
    #
    # ==== Options
    # Display options:
    # * <tt>:previous_label</tt> -- default: "« Previous" (this parameter is called <tt>:prev_label</tt> in versions <b>2.3.2</b> and older!)
    # * <tt>:next_label</tt> -- default: "Next »"
    # * <tt>:page_links</tt> -- when false, only previous/next links are rendered (default: true)
    # * <tt>:inner_window</tt> -- how many links are shown around the current page (default: 4)
    # * <tt>:outer_window</tt> -- how many links are around the first and the last page (default: 1)
    # * <tt>:separator</tt> -- string separator for page HTML elements (default: single space)
    # * <tt>:controls</tt> -- display controls only at the <tt>:top</tt> or <tt>:bottom</tt> of the pagination block (default: <tt>:both</tt>)
    # * <tt>:per_page</tt> -- number of items displayed per page (default: 10)
    #
    # HTML options:
    # * <tt>:class</tt> -- CSS class name for the generated DIV (default: "pagination")
    # * <tt>:container</tt> -- toggles rendering of the DIV container for pagination links, set to
    #   false only when you are rendering your own pagination markup (default: true)
    # * <tt>:id</tt> -- HTML ID for the container (default: nil). Pass +true+ to have the ID
    #   automatically generated from the class name of objects in collection: for example, paginating
    #   ArticleComment models would yield an ID of "article_comments_pagination".
    #
    # Advanced options:
    # * <tt>:param_name</tt> -- parameter name for page number in URLs (default: <tt>:page</tt>)
    # * <tt>:params</tt> -- additional parameters when generating pagination links
    #   (eg. <tt>:controller => "foo", :action => nil</tt>)
    # * <tt>:renderer</tt> -- class name, class or instance of a link renderer (default:
    #   <tt>Pagination::LinkRenderer</tt>)
    #
    # All options not recognized by paginate will become HTML attributes on the container
    # element for pagination links (the DIV). For example:
    #
    #   <% paginate @posts, :style => 'font-size: small' do |posts| %>
    #     ...
    #   <% end %>
    #
    # ... will result in:
    #
    #   <div class="pagination" style="font-size: small"> ... </div>
    #
    def paginate(collection = [], options = {}, &block)
      options = options.symbolize_keys.reverse_merge Pagination::ViewHelpers.pagination_options

      collection = Pagination::Collection.new(options.merge(:collection => collection, :current_page => params[options[:param_name]]|| 1))

      # get the renderer instance
      renderer = case options[:renderer]
      when String
        options[:renderer].to_s.constantize.new
      when Class
        options[:renderer].new
      else
        options[:renderer]
      end

      # render HTML for pagination
      renderer.prepare collection, options, self
      pagination = renderer.to_html.to_s

      if block_given?
        yield collection and return nil unless collection.total_pages > 1

        top = [:top, :both].include?(options[:controls]) ? pagination : ""
        bottom = [:bottom, :both].include?(options[:controls]) ? pagination : ""
        unless ActionView::Base.respond_to? :erb_variable
          concat top
          yield collection
          unless bottom.empty?
            concat bottom
          end
        else
          content = top + capture(&block) + bottom
          concat(content, block.binding)
        end
      else
        collection
      end
    end
  end

  # This class does the heavy lifting of actually building the pagination
  # links. It is used by the <tt>paginate</tt> helper internally.
  class LinkRenderer

    # The gap in page links is represented by:
    #
    #   <span class="gap">&hellip;</span>
    attr_accessor :gap_marker

    def initialize
      @gap_marker = '<span class="gap">&hellip;</span>'
    end

    # * +collection+ is a Pagination::Collection instance or any other object
    #   that conforms to that API
    # * +options+ are forwarded from +paginate+ view helper
    # * +template+ is the reference to the template being rendered
    def prepare(collection, options, template)
      @collection = collection
      @options    = options
      @template   = template

      # reset values in case we're re-using this instance
      @total_pages = @param_name = @url_string = nil
    end

    # Process it! This method returns the complete HTML string which contains
    # pagination links. Feel free to subclass LinkRenderer and change this
    # method as you see fit.
    def to_html
      links = @options[:page_links] ? windowed_links : []
      # previous/next buttons
      links.unshift page_link_or_span(@collection.previous_page, 'disabled prev_page', @options[:previous_label])
      links.push    page_link_or_span(@collection.next_page,     'disabled next_page', @options[:next_label])

      html = links.join(@options[:separator])
      @options[:container] ? @template.content_tag(:div, html, html_attributes) : html
    end

    # Returns the subset of +options+ this instance was initialized with that
    # represent HTML attributes for the container element of pagination links.
    def html_attributes
      return @html_attributes if @html_attributes
      @html_attributes = @options.except *(Pagination::ViewHelpers.pagination_options.keys - [:class])
      # pagination of Post models will have the ID of "posts_pagination"
      if @options[:container] and @options[:id] === true
        @html_attributes[:id] = @collection.first.class.name.underscore.pluralize + '_pagination'
      end<commit_msg>Added html_safe back<commit_after>module Pagination
  # = Pagination view helpers
  #
  # The main view helper, #paginate, renders
  # pagination links around (top and bottom) given collection. The helper itself is lightweight
  # and serves only as a wrapper around LinkRenderer instantiation; the
  # renderer then does all the hard work of generating the HTML.
  #
  # == Global options for helpers
  #
  # Options for pagination helpers are optional and get their default values from the
  # <tt>Pagination::ViewHelpers.pagination_options</tt> hash. You can write to this hash to
  # override default options on the global level:
  #
  #   Pagination::ViewHelpers.pagination_options[:previous_label] = 'Previous page'
  #
  # By putting this into "config/initializers/pagination.rb" (or simply environment.rb in
  # older versions of Rails) you can easily translate link texts to previous
  # and next pages, as well as override some other defaults to your liking.
  module ViewHelpers
    # default options that can be overridden on the global level
    @@pagination_options = {
      :class          => 'pagination',
      :previous_label => '&laquo; Previous',
      :next_label     => 'Next &raquo;',
      :inner_window   => 4, # links around the current page
      :outer_window   => 1, # links around beginning and end
      :separator      => ' ', # single space is friendly to spiders and non-graphic browsers
      :controls       => :both,
      :per_page       => 10,
      :param_name     => :page,
      :params         => nil,
      :renderer       => 'Pagination::LinkRenderer',
      :page_links     => true,
      :container      => true
    }
    mattr_reader :pagination_options

    # Renders Digg/Flickr-style pagination for a Pagination::Collection
    # object. Nil is returned if there is only one page in total; no point in
    # rendering the pagination in that case...
    #
    # ==== Options
    # Display options:
    # * <tt>:previous_label</tt> -- default: "« Previous" (this parameter is called <tt>:prev_label</tt> in versions <b>2.3.2</b> and older!)
    # * <tt>:next_label</tt> -- default: "Next »"
    # * <tt>:page_links</tt> -- when false, only previous/next links are rendered (default: true)
    # * <tt>:inner_window</tt> -- how many links are shown around the current page (default: 4)
    # * <tt>:outer_window</tt> -- how many links are around the first and the last page (default: 1)
    # * <tt>:separator</tt> -- string separator for page HTML elements (default: single space)
    # * <tt>:controls</tt> -- display controls only at the <tt>:top</tt> or <tt>:bottom</tt> of the pagination block (default: <tt>:both</tt>)
    # * <tt>:per_page</tt> -- number of items displayed per page (default: 10)
    #
    # HTML options:
    # * <tt>:class</tt> -- CSS class name for the generated DIV (default: "pagination")
    # * <tt>:container</tt> -- toggles rendering of the DIV container for pagination links, set to
    #   false only when you are rendering your own pagination markup (default: true)
    # * <tt>:id</tt> -- HTML ID for the container (default: nil). Pass +true+ to have the ID
    #   automatically generated from the class name of objects in collection: for example, paginating
    #   ArticleComment models would yield an ID of "article_comments_pagination".
    #
    # Advanced options:
    # * <tt>:param_name</tt> -- parameter name for page number in URLs (default: <tt>:page</tt>)
    # * <tt>:params</tt> -- additional parameters when generating pagination links
    #   (eg. <tt>:controller => "foo", :action => nil</tt>)
    # * <tt>:renderer</tt> -- class name, class or instance of a link renderer (default:
    #   <tt>Pagination::LinkRenderer</tt>)
    #
    # All options not recognized by paginate will become HTML attributes on the container
    # element for pagination links (the DIV). For example:
    #
    #   <% paginate @posts, :style => 'font-size: small' do |posts| %>
    #     ...
    #   <% end %>
    #
    # ... will result in:
    #
    #   <div class="pagination" style="font-size: small"> ... </div>
    #
    def paginate(collection = [], options = {}, &block)
      options = options.symbolize_keys.reverse_merge Pagination::ViewHelpers.pagination_options

      collection = Pagination::Collection.new(options.merge(:collection => collection, :current_page => params[options[:param_name]]|| 1))

      # get the renderer instance
      renderer = case options[:renderer]
      when String
        options[:renderer].to_s.constantize.new
      when Class
        options[:renderer].new
      else
        options[:renderer]
      end

      # render HTML for pagination
      renderer.prepare collection, options, self
      pagination = renderer.to_html.to_s

      if block_given?
        yield collection and return nil unless collection.total_pages > 1

        top = [:top, :both].include?(options[:controls]) ? pagination : ""
        bottom = [:bottom, :both].include?(options[:controls]) ? pagination : ""
        unless ActionView::Base.respond_to? :erb_variable
          concat top
          yield collection
          unless bottom.empty?
            concat bottom
          end
        else
          content = top + capture(&block) + bottom
          concat(content, block.binding)
        end
      else
        collection
      end
    end
  end

  # This class does the heavy lifting of actually building the pagination
  # links. It is used by the <tt>paginate</tt> helper internally.
  class LinkRenderer

    # The gap in page links is represented by:
    #
    #   <span class="gap">&hellip;</span>
    attr_accessor :gap_marker

    def initialize
      @gap_marker = '<span class="gap">&hellip;</span>'
    end

    # * +collection+ is a Pagination::Collection instance or any other object
    #   that conforms to that API
    # * +options+ are forwarded from +paginate+ view helper
    # * +template+ is the reference to the template being rendered
    def prepare(collection, options, template)
      @collection = collection
      @options    = options
      @template   = template

      # reset values in case we're re-using this instance
      @total_pages = @param_name = @url_string = nil
    end

    # Process it! This method returns the complete HTML string which contains
    # pagination links. Feel free to subclass LinkRenderer and change this
    # method as you see fit.
    def to_html
      links = @options[:page_links] ? windowed_links : []
      # previous/next buttons
      links.unshift page_link_or_span(@collection.previous_page, 'disabled prev_page', @options[:previous_label])
      links.push    page_link_or_span(@collection.next_page,     'disabled next_page', @options[:next_label])

      html = links.join(@options[:separator]).html_safe
      @options[:container] ? @template.content_tag(:div, html, html_attributes) : html
    end

    # Returns the subset of +options+ this instance was initialized with that
    # represent HTML attributes for the container element of pagination links.
    def html_attributes
      return @html_attributes if @html_attributes
      @html_attributes = @options.except *(Pagination::ViewHelpers.pagination_options.keys - [:class])
      # pagination of Post models will have the ID of "posts_pagination"
      if @options[:container] and @options[:id] === true
        @html_attributes[:id] = @collection.first.class.name.underscore.pluralize + '_pagination'
      end
{'fraction_non_alphanumeric': 0.10679090970034189, 'fraction_numerical': 0.0017429778105517194, 'mean_word_length': 2.963336875664187, 'pattern_counts': {'":': 0, '<': 115, '<?xml version=': 0, '>': 153, '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': '4487632', 'n_tokens_mistral': 4206, 'n_tokens_neox': 4105, 'n_words': 1429}