File: default_parser.rb

package info (click to toggle)
ruby-acts-as-taggable-on 11.0.0-2
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 596 kB
  • sloc: ruby: 3,924; makefile: 8
file content (77 lines) | stat: -rw-r--r-- 2,537 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# frozen_string_literal: true

module ActsAsTaggableOn
  ##
  # Returns a new TagList using the given tag string.
  #
  # Example:
  #   tag_list = ActsAsTaggableOn::DefaultParser.parse("One , Two,  Three")
  #   tag_list # ["One", "Two", "Three"]
  class DefaultParser < GenericParser
    def parse
      string = @tag_list

      string = string.join(ActsAsTaggableOn.glue) if string.respond_to?(:join)
      TagList.new.tap do |tag_list|
        string = string.to_s.dup

        string.gsub!(double_quote_pattern) do
          # Append the matched tag to the tag list
          tag_list << Regexp.last_match[2]
          # Return the matched delimiter ($3) to replace the matched items
          ''
        end

        string.gsub!(single_quote_pattern) do
          # Append the matched tag ($2) to the tag list
          tag_list << Regexp.last_match[2]
          # Return an empty string to replace the matched items
          ''
        end

        # split the string by the delimiter
        # and add to the tag_list
        tag_list.add(string.split(Regexp.new(delimiter)))
      end
    end

    # private
    def delimiter
      # Parse the quoted tags
      d = ActsAsTaggableOn.delimiter
      # Separate multiple delimiters by bitwise operator
      d = d.join('|') if d.is_a?(Array)
      d
    end

    # (             # Tag start delimiter ($1)
    # \A       |  # Either string start or
    # #{delimiter}        # a delimiter
    # )
    # \s*"          # quote (") optionally preceded by whitespace
    # (.*?)         # Tag ($2)
    # "\s*          # quote (") optionally followed by whitespace
    # (?=           # Tag end delimiter (not consumed; is zero-length lookahead)
    # #{delimiter}\s*  |  # Either a delimiter optionally followed by whitespace or
    # \z          # string end
    # )
    def double_quote_pattern
      /(\A|#{delimiter})\s*"(.*?)"\s*(?=#{delimiter}\s*|\z)/
    end

    # (             # Tag start delimiter ($1)
    # \A       |  # Either string start or
    # #{delimiter}        # a delimiter
    # )
    # \s*'          # quote (') optionally preceded by whitespace
    # (.*?)         # Tag ($2)
    # '\s*          # quote (') optionally followed by whitespace
    # (?=           # Tag end delimiter (not consumed; is zero-length lookahead)
    # #{delimiter}\s*  | d # Either a delimiter optionally followed by whitespace or
    # \z          # string end
    # )
    def single_quote_pattern
      /(\A|#{delimiter})\s*'(.*?)'\s*(?=#{delimiter}\s*|\z)/
    end
  end
end