class ComfortableMexicanSofa::Content::ParamsParser
Constants
- ARRAY_CLOSE
- ARRAY_OPEN
- COMMA
- HASH_CLOSE
- HASH_KEY
- HASH_OPEN
- IDENTIFIER
- STRING_LITERAL
Public Class Methods
new(string = "")
click to toggle source
@param <String> string
# File lib/comfortable_mexican_sofa/content/params_parser.rb, line 19 def initialize(string = "") @string = string end
Public Instance Methods
params()
click to toggle source
Takes CMS content tag parameters and converts them into array of strings, hashes and arrays.
@return [Array<String, {String => String}>] @raise [Error] if the given `text` is malformed.
@example
new("a, b, c").parse #=> ["a", "b", "c"] new("a, b: c, d: e").parse #=> ["a", {"b" => "c", "d" => "e"}] new("a, b: {c: [d, e]}").parse #=> ["a", {"b" => {"c" => ["d", "e"]}}]
# File lib/comfortable_mexican_sofa/content/params_parser.rb, line 39 def params @tokens = tokenize(@string) parse_params end
Private Instance Methods
parse_array()
click to toggle source
Array construction method. Will handle nested arrays
# File lib/comfortable_mexican_sofa/content/params_parser.rb, line 100 def parse_array opens = 1 array = [] while (token = @tokens.shift) case token&.first when :array_close opens -= 1 else array << parse_value(token) end return array if opens.zero? end raise Error, "Unclosed array param: #{@string}" end
parse_hash()
click to toggle source
Hash constructor method. Will handle nested hashes as well
# File lib/comfortable_mexican_sofa/content/params_parser.rb, line 73 def parse_hash opens = 1 hash = {} while (token = @tokens.shift) case token&.first when :hash_key hash[token[1]] = parse_value(@tokens.shift) when :hash_close opens -= 1 when :hash_open opens += 1 else raise Error, "Invalid params: #{@string}" end return hash if opens.zero? end # We're can't really detect unclosed hashes as we can construct them without # opening brakets. For example, `a: b, c: d` is same as `{a: b, c: d}` and # `{a: b, c: d` is also ends up to be a valid hash. It will error out if # unclosed hash is followed by some other unexpected token. Like: `{a: b, c` hash end
parse_params()
click to toggle source
Contructs root-level list of arguments sent via content tag
# File lib/comfortable_mexican_sofa/content/params_parser.rb, line 47 def parse_params params = [] while (token = @tokens.shift) params << parse_value(token) end params end
parse_value(token)
click to toggle source
Gets token value. Will trigger parsing of hash and array structures
# File lib/comfortable_mexican_sofa/content/params_parser.rb, line 56 def parse_value(token) case token&.first when :string token[1] when :hash_key @tokens.unshift(token) parse_hash when :hash_open parse_hash when :array_open parse_array else raise Error, "Invalid params: #{@string}" end end
tokenize(args_string)
click to toggle source
Tokenizing input string into a list of touples Also args_string is stripped of “smart” quotes coming from wysiwyg
@param [String] args_string @return [Array<String>] tokens
# File lib/comfortable_mexican_sofa/content/params_parser.rb, line 122 def tokenize(args_string) args_string = args_string.tr("“”‘’", %q(""'')) ss = StringScanner.new(args_string) tokens = [] loop do ss.skip(%r{\s*}) break if ss.eos? # commas are just separators like spaces next if ss.scan(COMMA) tokens << if (t = ss.scan(STRING_LITERAL)) then [:string, t[1...-1]] elsif (t = ss.scan(HASH_KEY)) then [:hash_key, t[0...-1]] elsif (t = ss.scan(IDENTIFIER)) then [:string, t] elsif (t = ss.scan(HASH_OPEN)) then [:hash_open, t] elsif (t = ss.scan(HASH_CLOSE)) then [:hash_close, t] elsif (t = ss.scan(ARRAY_OPEN)) then [:array_open, t] elsif (t = ss.scan(ARRAY_CLOSE)) then [:array_close, t] else raise Error, "Unexpected char: #{ss.getch}" end end tokens end