def _parse_string_set(self, value): # string-set may set multiple strings (separated by commas) # For example: # { string-set: string1 "value1", string2 "value2", string3 counter(item, decimal); } # Also, we can't just split on commas because for example target-text() has commas in it # This first piece is just a glorified split(',') stream = TokenStream(cssselect.tokenize(value)) values = [] acc = '' parentheses = 0 while stream.peek() is not None: token = stream.next() if str(token) == ',' and parentheses == 0: values.append(acc) acc = '' else: if str(token) == '(': parentheses += 1 elif str(token) == ')': parentheses -= 1 if type(token) == String: acc += '"%s" ' % str(token) else: acc += str(token) + ' ' if acc != '': values.append(acc) acc = [] for val in values: stream = TokenStream(cssselect.tokenize(val)) string_name = str(stream.next()) string_value = val[len(string_name) + 1:] acc.append((string_name, ContentPropertyParser().parse(string_value))) return acc
def parse(self, value): """ Given a string like "'Exercise ' target-counter(attr(href, url), chapter, decimal) counters(section)" return a list of the form: (function-name or None, values) """ vals = [] stream = TokenStream(cssselect.tokenize(value)) while stream.peek() is not None: t = stream.next() if isinstance(t, String): vals.append((None, str(t))) else: name = str(t) val = None method = '_parse_' + name.replace('-', '_') if hasattr(self, method): method = getattr(self, method) val = method(stream) #else: # name = ContentPropertyParser.UNKNOWN # val = [t].concat(self._unknown(stream)) # If anything fails parsing (ie it's None) then the whole line is unusable if val is None: return None vals.append((name, val)) return vals
def _counter(self, value, default): acc = [] stream = TokenStream(cssselect.tokenize(value)) while stream.peek() is not None: name = str(stream.next()) by = default if _is_int(str(stream.peek())): by = int(str(stream.next())) acc.append((name, by)) return acc