code: func lexIdent(l *lexer) stateFn {
  	// the different idents start with different unique characters.
  	// peel those off.
  	var itemType = itemIdent
  	switch l.next() {
  	case '.':
  		if isDigit(l.next()) {
  			itemType = itemDotIndex
  		} else {
  			itemType = itemDotIdent
  		}
  		l.backup()
  	case '$':
  		itemType = itemDollarIdent
  	case '/':
  		itemType = itemCommandEnd
  	case '\\':
  		itemType = itemSpecialChar
  	case '?':
  		dot := l.next()
  		if dot != '.' {
  			l.errorf("unexpected beginning to ident: ?%v", dot)
  		}
  		if isDigit(l.next()) {
  			itemType = itemQuestionDotIndex
  		} else {
  			itemType = itemQuestionDotIdent
  		}
  		l.backup()
  	}
  
  	// absorb the rest of the identifier
  	for isAlphaNumeric(l.next()) {
  	}
  	l.backup()
  	word := l.input[l.start:l.pos]
  
  	// if it's a builtin, return that item type
  	if itemType, ok := builtinIdents[word]; ok {
  		l.emit(itemType)
  		// {literal} and {css} have unusual lexing rules
  		switch itemType {
  		case itemLiteral:
  			return lexLiteral
  		case itemCss:
  			return lexCss
  		}
  		return lexInsideTag
  	}
  	// if not a builtin, it shouldn't start with / or \
  	if itemType == itemCommandEnd || itemType == itemSpecialChar {
  		var str = l.input[l.start:l.pos]
  		l.pos = l.start
  		return l.errorf("unrecognized identifier %q", str)
  	}
  
  	// else, use the type determined at the beginning.
  	l.emit(itemType)
  	return lexInsideTag
  }
docs: // lexIdent recognizes the various kinds of identifiers