I believe I now have a working wikilink lexer
parent
4bc6d7ceda
commit
949b5c240e
@ -1,118 +1,130 @@
|
||||
package wikilink
|
||||
|
||||
import (
|
||||
"log"
|
||||
"strings"
|
||||
"unicode"
|
||||
)
|
||||
|
||||
func lexFragment(l *Lexer) stateFn {
|
||||
log.Println("entering lexFragment")
|
||||
for {
|
||||
if strings.HasPrefix(l.input[l.pos:], CloseLink) {
|
||||
return lexCloseLink
|
||||
func isOpenLink(s string) bool {
|
||||
return strings.HasPrefix(s, OpenLink)
|
||||
}
|
||||
|
||||
if l.peek() == '^' {
|
||||
l.next()
|
||||
l.emit(ItemFragment)
|
||||
l.acceptRun("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 -.,")
|
||||
|
||||
return lexInsideLink
|
||||
func isCloseLink(s string) bool {
|
||||
return strings.HasPrefix(s, CloseLink)
|
||||
}
|
||||
|
||||
return lexInsideLink
|
||||
}
|
||||
func isAlias(s string) bool {
|
||||
return strings.HasPrefix(s, Alias)
|
||||
}
|
||||
|
||||
func lexAlias(l *Lexer) stateFn {
|
||||
// l.accept
|
||||
log.Println("entering lexAlias")
|
||||
for {
|
||||
if strings.HasPrefix(l.input[l.pos:], CloseLink) {
|
||||
return lexCloseLink
|
||||
func isHeading(s string) bool {
|
||||
return strings.HasPrefix(s, Heading)
|
||||
}
|
||||
r := l.next()
|
||||
|
||||
}
|
||||
l.emit(ItemAlias)
|
||||
|
||||
return lexInsideLink
|
||||
func isBlockRef(s string) bool {
|
||||
return strings.HasPrefix(s, BlockRef)
|
||||
}
|
||||
|
||||
func lexIdent(l *Lexer) stateFn {
|
||||
for {
|
||||
if strings.HasPrefix(l.input[l.pos:], CloseLink) {
|
||||
r := l.next()
|
||||
s := l.input[l.pos:]
|
||||
if r == '\\' { // i think this will handle escape characters?
|
||||
break
|
||||
}
|
||||
switch {
|
||||
case isBlockRef(s):
|
||||
l.emit(ItemIdent)
|
||||
return lexBlockRef
|
||||
case isAlias(s):
|
||||
l.emit(ItemIdent)
|
||||
return lexAlias
|
||||
case isCloseLink(s):
|
||||
l.emit(ItemIdent)
|
||||
return lexCloseLink
|
||||
case isHeading(s):
|
||||
l.emit(ItemIdent)
|
||||
return lexHeading
|
||||
}
|
||||
// r := l.next()
|
||||
}
|
||||
return lexInsideLink
|
||||
return nil
|
||||
}
|
||||
|
||||
func lexInsideLink(l *Lexer) stateFn {
|
||||
log.Println("entering lexInsideLink")
|
||||
func lexHeading(l *Lexer) stateFn {
|
||||
l.pos += len(Heading)
|
||||
l.emit(ItemHeading)
|
||||
|
||||
for {
|
||||
if strings.HasPrefix(l.input[l.pos:], CloseLink) {
|
||||
return lexCloseLink
|
||||
return lexIdent
|
||||
}
|
||||
|
||||
r := l.next()
|
||||
log.Printf("inspecting %q\n", string(r))
|
||||
func lexBlockRef(l *Lexer) stateFn {
|
||||
l.pos += len(BlockRef)
|
||||
l.emit(ItemBlockRef)
|
||||
|
||||
switch {
|
||||
case r == EOF:
|
||||
case r == '\n':
|
||||
return l.errorf("unclosed link")
|
||||
case r == '#':
|
||||
l.emit(ItemText)
|
||||
return lexIdent
|
||||
}
|
||||
|
||||
return lexFragment
|
||||
case r == '|':
|
||||
l.emit(ItemText)
|
||||
func lexAlias(l *Lexer) stateFn {
|
||||
l.pos += len(Alias)
|
||||
l.emit(ItemAlias)
|
||||
|
||||
return lexAlias
|
||||
return lexIdent
|
||||
}
|
||||
|
||||
func lexText(l *Lexer) stateFn {
|
||||
for {
|
||||
if isOpenLink(l.input[l.pos:]) {
|
||||
return lexOpenLink
|
||||
}
|
||||
r := l.next()
|
||||
switch {
|
||||
case r == EOF || r == '\n':
|
||||
return l.errorf("wikilink terminated incorrectly")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func lexOpenLink(l *Lexer) stateFn {
|
||||
log.Println("entering lexOpenLink")
|
||||
l.pos += len(OpenLink)
|
||||
l.emit(ItemOpenLink)
|
||||
|
||||
return lexInsideLink
|
||||
return lexIdent
|
||||
}
|
||||
|
||||
func lexCloseLink(l *Lexer) stateFn {
|
||||
log.Println("entering lexCloseLink")
|
||||
l.pos += len(CloseLink)
|
||||
l.emit(ItemCloseLink)
|
||||
|
||||
return lexText
|
||||
}
|
||||
|
||||
func lexText(l *Lexer) stateFn {
|
||||
log.Println("entering lexText")
|
||||
/*
|
||||
func lexInsideLink(l *Lexer) stateFn {
|
||||
log.Println("entering lexInsideLink")
|
||||
|
||||
for {
|
||||
if strings.HasPrefix(l.input[l.pos:], OpenLink) {
|
||||
if l.pos > l.start {
|
||||
l.emit(ItemText)
|
||||
if strings.HasPrefix(l.input[l.pos:], CloseLink) {
|
||||
return lexCloseLink
|
||||
}
|
||||
|
||||
return lexOpenLink
|
||||
}
|
||||
r := l.next()
|
||||
log.Printf("inspecting %q\n", string(r))
|
||||
|
||||
if l.next() == EOF {
|
||||
break
|
||||
}
|
||||
if l.pos > l.start {
|
||||
switch {
|
||||
case r == EOF:
|
||||
case r == '\n':
|
||||
return l.errorf("unclosed link")
|
||||
case r == '#':
|
||||
l.emit(ItemText)
|
||||
if l.peek() = '^' { return lexBlockRef }
|
||||
|
||||
return lexHeading
|
||||
case r == '|':
|
||||
l.emit(ItemText)
|
||||
|
||||
return lexAlias
|
||||
}
|
||||
l.emit(ItemEOF)
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
*/
|
||||
|
Loading…
Reference in New Issue