package mardown import "fmt" type lexerType string const ( lexerBreak lexerType = "break" lexerModifier lexerType = "modifier" lexerCode lexerType = "code" lexerHeader lexerType = "header" lexerQuote lexerType = "quote" lexerLiteral lexerType = "literal" ) type lexer struct { Type lexerType Value string } func (l *lexer) String() string { return fmt.Sprintf("%s(%s)", l.Type, l.Value) } type lexers struct { current int lexers []lexer } func (l *lexers) Next() lexer { l.current++ return l.lexers[l.current] } func (l *lexers) Finished() bool { return l.current+1 >= len(l.lexers) } func lex(s string) *lexers { lxs := &lexers{current: -1} var lexs []lexer var currentType lexerType var previous string fn := func(c rune, t lexerType) { if currentType != t && len(previous) > 0 { lexs = append(lexs, lexer{Type: currentType, Value: previous}) previous = "" } currentType = t previous += string(c) } for _, c := range []rune(s) { switch c { case '*', '_': fn(c, lexerModifier) case '`': fn(c, lexerCode) case '\n': fn(c, lexerBreak) case '#': fn(c, lexerHeader) case '>': fn(c, lexerQuote) default: fn(c, lexerLiteral) } } lxs.lexers = lexs return lxs }