Sha256: b27ab964728152503251bdb4f2990f9db9ff14ba556b97462008f8534bc60900

Contents?: true

Size: 1.44 KB

Versions: 32

Compression:

Stored size: 1.44 KB

Contents

require 'singleton'

module GovukTechDocs
  class UniqueIdentifierGenerator
    include Singleton

    Anchor = Struct.new(:id, :level)

    attr_reader :anchors

    def initialize
      reset
    end

    def create(id, level)
      anchor = heading_slug(id)

      unless unique?(anchor)
        anchor = prefixed_by_parent(anchor, level)
      end

      unless unique?(anchor)
        anchor = suffixed_with_number(anchor)
      end

      @anchors << Anchor.new(anchor, level)

      anchor
    end

    def reset
      @anchors = []
    end

  private

    def prefixed_by_parent(anchor, level)
      closest_parent = @anchors.reverse.find { |a| a.level < level }
      if closest_parent.nil?
        anchor
      else
        [closest_parent.id, anchor].join("-")
      end
    end

    def suffixed_with_number(text)
      number = 2
      anchor = "#{text}-#{number}"

      until unique?(anchor)
        anchor = "#{text}-#{number}"
        number += 1
      end

      anchor
    end

    def unique?(value)
      @anchors.none? { |a| a.id == value }
    end

    # https://github.com/vmg/redcarpet/blob/820dadb98b3720811cc20c5570a5d43c796c85fc/ext/redcarpet/html.c#L274-L305
    def heading_slug(text)
      text
        .downcase
        .strip
        .gsub(%r{</?[^>]+?>}, '') # Remove HTML tags
        .gsub(/[^0-9a-z]+/, '-')  # Replace non-alphanumeric characters with dashes
        .gsub(/\A-+|-+\z/, '')    # Remove trailing dashes
    end
  end
end

Version data entries

32 entries across 32 versions & 2 rubygems

Version Path
govuk_tech_docs-2.0.7 lib/govuk_tech_docs/unique_identifier_generator.rb
govuk_tech_docs-2.0.6 lib/govuk_tech_docs/unique_identifier_generator.rb
govuk_tech_docs-2.0.5 lib/govuk_tech_docs/unique_identifier_generator.rb
govuk_tech_docs-2.0.4 lib/govuk_tech_docs/unique_identifier_generator.rb
govuk_tech_docs-2.0.3 lib/govuk_tech_docs/unique_identifier_generator.rb
govuk_tech_docs-2.0.2 lib/govuk_tech_docs/unique_identifier_generator.rb
govuk_tech_docs-2.0.1 lib/govuk_tech_docs/unique_identifier_generator.rb
govuk_tech_docs-2.0.0.pre.test.pre.release.pre.525 lib/govuk_tech_docs/unique_identifier_generator.rb
govuk_tech_docs-2.0.0.pre.test.pre.release.pre.524 lib/govuk_tech_docs/unique_identifier_generator.rb
govuk_tech_docs-2.0.0.test.pre.release.521 lib/govuk_tech_docs/unique_identifier_generator.rb
govuk_tech_docs-2.0.0 lib/govuk_tech_docs/unique_identifier_generator.rb
govuk_tech_docs-1.9.0.pre.rc2 lib/govuk_tech_docs/unique_identifier_generator.rb
govuk_tech_docs-1.9.0.pre.gfe lib/govuk_tech_docs/unique_identifier_generator.rb
govuk_tech_docs-1.8.3 lib/govuk_tech_docs/unique_identifier_generator.rb
dss_tech_docs-0.1.2 lib/govuk_tech_docs/unique_identifier_generator.rb
dss_tech_docs-0.1.1 lib/govuk_tech_docs/unique_identifier_generator.rb
dss_tech_docs-0.1.0 lib/govuk_tech_docs/unique_identifier_generator.rb
govuk_tech_docs-1.8.2 lib/govuk_tech_docs/unique_identifier_generator.rb
govuk_tech_docs-1.8.1 lib/govuk_tech_docs/unique_identifier_generator.rb
govuk_tech_docs-1.8.0 lib/govuk_tech_docs/unique_identifier_generator.rb