func lexValue(l *lexer) stateFn {
Loop:
	for {
		switch r := l.next(); {
		case isValueChar(r):
		default:
			l.backup()
			l.emit(itemValue)
			break Loop
		}
	}
	return lexNewLine
}
lexValue scans the value in the content line

value      = *VALUE-CHAR
VALUE-CHAR = WSP / %x21-7E / NON-US-ASCII ; Any textual character
package ical
import (
	"fmt"
	"strings"
	"unicode"
	"unicode/utf8"
)
type item struct {
	typ itemType  
	pos int       
	val string    
}
func (i item) String() string {
	switch {
	case i.typ == itemEOF:
		return "EOF"
	case i.typ == itemError:
		return i.val
	case i.typ > itemKeyword:
		return fmt.Sprintf("<%s>", i.val)
	case len(i.val) > 10:
		return fmt.Sprintf("%.10q...", i.val)
	}
	return fmt.Sprintf("%q", i.val)
}
type itemType int
const (
	itemError itemType = iota
	itemEOF
	itemLineEnd
	itemName
	itemParamName
	itemParamValue
	itemValue
	itemColon      
	itemSemiColon  
	itemEqual      
	itemComma      
	itemKeyword  
	itemBeginVCalendar
	itemEndVCalendar
	itemBeginVEvent
	itemEndVEvent
	itemBeginVAlarm
	itemEndVAlarm
)
var key = map[string]itemType{
	"BEGIN:VCALENDAR": itemBeginVCalendar,
	"END:VCALENDAR":   itemEndVCalendar,
	"BEGIN:VEVENT":    itemBeginVEvent,
	"END:VEVENT":      itemEndVEvent,
	"BEGIN:VALARM":    itemBeginVAlarm,
	"END:VALARM":      itemEndVAlarm,
}
const eof = -1
type stateFn func(*lexer) stateFn
type lexer struct {
	input   string     
	state   stateFn    
	start   int        
	pos     int        
	width   int        
	lastPos int        
	items   chan item  
}
func lex(input string) *lexer {
	l := &lexer{
		input: input,
		items: make(chan item),
	}
	go l.run()  
	return l
}
func (l *lexer) run() {
	for l.state = lexName; l.state != nil; {
		l.state = l.state(l)
	}
	close(l.items)  
}
func (l *lexer) emit(t itemType) {
	l.items <- item{t, l.start, l.input[l.start:l.pos]}
	l.start = l.pos
}
func (l *lexer) ignore() {
	l.start = l.pos
}
func (l *lexer) next() rune {
	if int(l.pos) >= len(l.input) {
		l.width = 0
		return eof
	}
	r, w := utf8.DecodeRuneInString(l.input[l.pos:])
	l.width = w
	l.pos += l.width
	return r
}
func (l *lexer) peek() rune {
	r := l.next()
	l.backup()
	return r
}
func (l *lexer) backup() {
	l.pos -= l.width
}
func (l *lexer) errorf(format string, args ...interface{}) stateFn {
	l.items <- item{itemError, l.start, fmt.Sprintf(format, args...)}
	return nil
}
func (l *lexer) nextItem() item {
	item := <-l.items
	l.lastPos = item.pos
	return item
}
const (
	crlf           = "\r\n"
	beginVCalendar = "BEGIN:VCALENDAR"
	endVCalendar   = "END:VCALENDAR"
	beginVEvent    = "BEGIN:VEVENT"
	endVEvent      = "END:VEVENT"
	beginValarm    = "BEGIN:VALARM"
	endVAlarm      = "END:VALARM"
)
func lexContentLine(l *lexer) stateFn {
	switch r := l.next(); {
	case r == ';':
		l.emit(itemSemiColon)
		return lexParamName
	case r == ':':
		l.emit(itemColon)
		return lexValue
	case r == ',':
		l.emit(itemComma)
		return lexParamValue
	default:
		return l.errorf("unrecognized character in action: %#U", r)
	}
}
func lexNewLine(l *lexer) stateFn {
	if l.peek() == eof {
		return nil
	}
	if !strings.HasPrefix(l.input[l.pos:], crlf) {
		l.errorf("unable to find end of line \"CRLF\"")
	}
	l.pos += len(crlf)
	l.emit(itemLineEnd)
	if l.next() == eof {
		l.emit(itemEOF)
		return nil
	}
	l.backup()
	return lexName
}
func lexName(l *lexer) stateFn {
	if strings.HasPrefix(l.input[l.pos:], beginVCalendar) {
		l.pos += len(beginVCalendar)
		l.emit(itemBeginVCalendar)
		return lexNewLine
	}
	if strings.HasPrefix(l.input[l.pos:], endVCalendar) {
		l.pos += len(endVCalendar)
		l.emit(itemEndVCalendar)
		return lexNewLine
	}
	if strings.HasPrefix(l.input[l.pos:], beginVEvent) {
		l.pos += len(beginVEvent)
		l.emit(itemBeginVEvent)
		return lexNewLine
	}
	if strings.HasPrefix(l.input[l.pos:], endVEvent) {
		l.pos += len(endVEvent)
		l.emit(itemEndVEvent)
		return lexNewLine
	}
	if strings.HasPrefix(l.input[l.pos:], beginValarm) {
		l.pos += len(beginValarm)
		l.emit(itemBeginVAlarm)
		return lexNewLine
	}
	if strings.HasPrefix(l.input[l.pos:], endVAlarm) {
		l.pos += len(endVAlarm)
		l.emit(itemEndVAlarm)
		return lexNewLine
	}
Loop:
	for {
		switch r := l.next(); {
		case isName(r):
		default:
			l.backup()
			l.emit(itemName)
			break Loop
		}
	}
	return lexContentLine
}
func lexParamName(l *lexer) stateFn {
Loop:
	for {
		switch r := l.next(); {
		case isName(r):
		default:
			l.backup()
			l.emit(itemParamName)
			break Loop
		}
	}
	r := l.next()
	if r == '=' {
		l.emit(itemEqual)
		return lexParamValue
	}
	return l.errorf("missing \"=\" sign after param name, got %#U", r)
}
func lexParamValue(l *lexer) stateFn {
	r := l.next()
	if r == '"' {
		l.ignore()
	QLoop:
		for {
			switch r := l.next(); {
			case isQSafeChar(r):
			default:
				l.backup()
				l.emit(itemParamValue)
				break QLoop
			}
		}
		r := l.next()
		if r != '"' {
			l.errorf("Missing \" for closing value")
		} else {
			l.ignore()
		}
	} else {
		l.backup()
	Loop:
		for {
			switch r := l.next(); {
			case isSafeChar(r):
			default:
				l.backup()
				l.emit(itemParamValue)
				break Loop
			}
		}
	}
	return lexContentLine
}