Sha256: cb47b567edc4b420341bcf8fd7d0090b78a7cc852886f52ca223403d904fa24c

Contents?: true

Size: 1.91 KB

Versions: 17

Compression:

Stored size: 1.91 KB

Contents

# frozen_string_literal: true

module Decidim
  module ContentParsers
    # A parser that searches hashtags in content.
    #
    # A word starting with `#` will be considered as a hashtag if
    # it only contains letters, numbers or underscores. If the `#` is
    # followed with an underscore, then it is not considered.
    #
    # @see BaseParser Examples of how to use a content parser
    class HashtagParser < TagParser
      # Class used as a container for metadata
      #
      # @!attribute hashtags
      #   @return [Array] an array of Decidim::Hashtag mentioned in content
      Metadata = Struct.new(:hashtags)

      # Matches a hashtag if it starts with a letter or number
      # and only contains letters, numbers or underscores.
      HASHTAG_REGEX = /(?:\A|\s\K)\B#([[:alnum:]](?:[[:alnum:]]|_)*)\b/i

      def metadata
        Metadata.new(content_tags.map { |content_hashtag| hashtag(content_hashtag) }.uniq)
      end

      private

      def tag_data_type
        "hashtag"
      end

      def replace_tags(text)
        text.gsub(HASHTAG_REGEX) do |match|
          "#{hashtag(match[1..-1]).to_global_id}/#{extra_hashtags? ? "_" : ""}#{match[1..-1]}"
        end
      end

      def scan_tags(text)
        text.scan(HASHTAG_REGEX)
      end

      def hashtag(name)
        hashtags[name.downcase] ||= Decidim::Hashtag.create(organization: current_organization, name: name.downcase)
      end

      def hashtags
        @hashtags ||= existing_hashtags.index_by(&:name)
      end

      def existing_hashtags
        @existing_hashtags ||= Decidim::Hashtag.where(organization: current_organization, name: content_tags.map(&:downcase))
      end

      def current_organization
        @current_organization ||= context[:current_organization]
      end

      def extra_hashtags?
        return @extra_hashtags if defined?(@extra_hashtags)

        @extra_hashtags = context[:extra_hashtags]
      end
    end
  end
end

Version data entries

17 entries across 17 versions & 1 rubygems

Version Path
decidim-core-0.30.0.rc2 lib/decidim/content_parsers/hashtag_parser.rb
decidim-core-0.30.0.rc1 lib/decidim/content_parsers/hashtag_parser.rb
decidim-core-0.29.2 lib/decidim/content_parsers/hashtag_parser.rb
decidim-core-0.28.5 lib/decidim/content_parsers/hashtag_parser.rb
decidim-core-0.29.1 lib/decidim/content_parsers/hashtag_parser.rb
decidim-core-0.28.4 lib/decidim/content_parsers/hashtag_parser.rb
decidim-core-0.29.0 lib/decidim/content_parsers/hashtag_parser.rb
decidim-core-0.28.3 lib/decidim/content_parsers/hashtag_parser.rb
decidim-core-0.29.0.rc4 lib/decidim/content_parsers/hashtag_parser.rb
decidim-core-0.29.0.rc3 lib/decidim/content_parsers/hashtag_parser.rb
decidim-core-0.29.0.rc2 lib/decidim/content_parsers/hashtag_parser.rb
decidim-core-0.29.0.rc1 lib/decidim/content_parsers/hashtag_parser.rb
decidim-core-0.28.2 lib/decidim/content_parsers/hashtag_parser.rb
decidim-core-0.28.1 lib/decidim/content_parsers/hashtag_parser.rb
decidim-core-0.28.0 lib/decidim/content_parsers/hashtag_parser.rb
decidim-core-0.28.0.rc5 lib/decidim/content_parsers/hashtag_parser.rb
decidim-core-0.28.0.rc4 lib/decidim/content_parsers/hashtag_parser.rb