func (l *lexer) isNotEmpty() bool {
	return l.pos > l.start
}
hasText returns true if the current parsed text is not empty.
package properties
import (
	"fmt"
	"strconv"
	"strings"
	"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 len(i.val) > 10:
		return fmt.Sprintf("%.10q...", i.val)
	}
	return fmt.Sprintf("%q", i.val)
}
type itemType int
const (
	itemError itemType = iota  
	itemEOF
	itemKey      
	itemValue    
	itemComment  
)
const eof = -1
const whitespace = " \f\t"
type stateFn func(*lexer) stateFn
type lexer struct {
	input   string     
	state   stateFn    
	pos     int        
	start   int        
	width   int        
	lastPos int        
	runes   []rune     
	items   chan item  
}
func (l *lexer) next() rune {
	if 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) emit(t itemType) {
	i := item{t, l.start, string(l.runes)}
	l.items <- i
	l.start = l.pos
	l.runes = l.runes[:0]
}
func (l *lexer) ignore() {
	l.start = l.pos
}
func (l *lexer) appendRune(r rune) {
	l.runes = append(l.runes, r)
}
func (l *lexer) accept(valid string) bool {
	if strings.ContainsRune(valid, l.next()) {
		return true
	}
	l.backup()
	return false
}
func (l *lexer) acceptRun(valid string) {
	for strings.ContainsRune(valid, l.next()) {
	}
	l.backup()
}
func (l *lexer) acceptRunUntil(term rune) {
	for term != l.next() {
	}
	l.backup()
}