module Archetype::SassExtensions::Styleguide private # # given a sentence, deconstruct it into it's identifier and verbages # # *Parameters*: # - sentence {String|List} the sentence describing the component # - theme {String} the theme to use # - state {String} the name of a state to return # *Returns*: # - {Array} an array containing the identifer, modifiers, and a token # def grammar(sentence, theme = nil, state = nil) theme = get_theme(theme) components = theme[:components] # get a list of valid ids styleguideIds = components.keys sentence = sentence.split if sentence.is_a? String id, modifiers = grammarize(sentence, styleguideIds) # if there was no id, return a list of valid IDs for reporting modifiers = styleguideIds if id.nil? # get the list of currenty installed component extensions extensions = theme[:extensions] if not id.nil? # TODO - low - eoneill: make sure we always want to return unique modifiers # i can't think of a case where we wouldn't want to remove dups # maybe in the case where we're looking for strict keys on the lookup? modifiers = modifiers.uniq token = memoizer.tokenize(theme[:name], extensions, id, modifiers, state) return id, modifiers, token end # # given a sentence, convert it to it's internal representation # # *Parameters*: # - sentence {Array|List} the sentence describing the component # - ids {Array} the list of identifiers # *Returns*: # - {Array} an array containing the identifer and modifiers # def grammarize(sentence, ids = []) sentence = sentence.to_a id = nil modifiers = [] if not sentence.empty? prefix = '' order = '' # these define various attributes for modifiers (e.g. `button with a shadow`) extras = %w(on with without) # these are things that are useless to us, so we just leave them out ignore = %w(a an also the this that is was it) # these are our context switches (e.g. `headline in a button`) contexts = %w(in within) sentence.each do |item| item = item.value if not item.is_a?(String) # find the ID if id.nil? and ids.include?(item) and prefix.empty? and order.empty? id = item # if it's a `context`, we need to increase the depth and reset the prefix elsif contexts.include?(item) order = "#{item}-#{order}" prefix = '' # if it's an `extra`, we update the prefix elsif extras.include?(item) prefix = "#{item}-" # finally, check that it's not on the ignore (useless) list. if it is, we just skip over it # (maybe this should be the first thing we check?) elsif not ignore.include?(item) modifiers.push("#{order}#{prefix}#{item}") end end end return id, modifiers end end