def eval_string_value(self, element, value):
        """Evaluate parsed string.

        Returns a list of current and delayed values.
        """
        strval = ''
        vals = []

        for term in value:
            if type(term) is ast.WhitespaceToken:
                pass

            elif type(term) is ast.StringToken:
                strval += term.value

            elif type(term) is ast.IdentToken:
                log(DEBUG, u"IdentToken as string: {}".format(
                    term.value).encode('utf-8'))
                strval += term.value

            elif type(term) is ast.LiteralToken:
                log(DEBUG, u"LiteralToken as string: {}".format(
                    term.value).encode('utf-8'))
                strval += term.value

            elif type(term) is ast.FunctionBlock:
                if term.name == 'string':
                    str_args = split(term.arguments, ',')
                    str_name = self.eval_string_value(element,
                                                      str_args[0])[0]
                    val = self.lookup('strings', str_name)
                    if val == '':
                        if len(str_args) > 1:
                            val = self.eval_string_value(element,
                                                         str_args[1])[0]
                        else:
                            log(WARN, u"{} blank string"
                                .format(str_name).encode('utf-8'))
                    strval += val

                elif term.name == u'attr':
                    att_args = split(term.arguments, ',')
                    att_name = self.eval_string_value(element,
                                                      att_args[0])[0]
                    att_def = ''
                    if len(att_args) > 1:
                        att_def = self.eval_string_value(element,
                                                         att_args[1])[0]
                    if '|' in att_name:
                        ns, att = att_name.split('|')
                        try:
                            ns = self.css_namespaces[ns]
                        except KeyError:
                            log(WARN, u"Undefined namespace prefix {}"
                                .format(ns).encode('utf-8'))
                            continue
                        att_name = etree.QName(ns, att)
                    strval += element.etree_element.get(att_name, att_def)

                elif term.name == u'uuid':
                    strval += self.generate_id()

                elif term.name == u'content':
                    strval += etree.tostring(element.etree_element,
                                             encoding='unicode',
                                             method='text',
                                             with_tail=False)

                elif term.name.startswith('target-'):
                    if strval:
                        vals.append(strval)
                        strval = ''
                    target_args = split(term.arguments, ',')
                    vref = self.eval_string_value(element,
                                                  target_args[0])[0]
                    vname = self.eval_string_value(element,
                                                   target_args[1])[0]

                    vtype = term.name[7:]+'s'
                    vals.append(TargetVal(self, vref[1:], vname, vtype))

                elif term.name == u'first-letter':
                    tmpstr = self.eval_string_value(element, term.arguments)
                    if tmpstr:
                        if isinstance(tmpstr[0], basestring):
                            strval += tmpstr[0][0]
                        else:
                            log(WARN, u"Bad string value:"
                                u" nested target-* not allowed. "
                                u"{}".format(
                                    serialize(value)).encode(
                                        'utf-8'))

                    # FIXME can we do delayed first-letter

                elif term.name == 'counter':
                    counterargs = [serialize(t).strip(" \'")
                                   for t in split(term.arguments, ',')]
                    count = self.lookup('counters', counterargs)
                    strval += str(count)

                elif term.name == u'pending':
                    log(WARN, u"Bad string value: pending() not allowed. "
                        u"{}".format(serialize(value)).encode(
                                       'utf-8'))
                else:
                    log(WARN, u"Bad string value: unknown function: {}. "
                        u"{}".format(term.name, serialize(value)).encode(
                            'utf-8'))

        if strval:
            vals.append(strval)
        return vals