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
|