amu/parser/image.go

87 lines
1.9 KiB
Go

package parser
import (
"bytes"
"strings"
"go.arsenm.dev/amu/ast"
"go.arsenm.dev/amu/scanner"
)
// parseImage attempts to parse an image
func (p *Parser) parseImage() *ast.Image {
// Create new image
img := &ast.Image{}
// Create buffers for image properties
altBuf := &bytes.Buffer{}
srcBuf := &bytes.Buffer{}
linkBuf := &bytes.Buffer{}
// Set current buffer to alt text buffer
currentBuf := altBuf
// Scan token
tok, lit := p.scan()
// If token is not PUNCT or literal is not "["
if tok != scanner.PUNCT || lit != "[" {
// Return nil as this is not a valid image
return nil
}
// Declare variable for last literal
var lastLit string
parseLoop:
for {
// Scan token
tok, lit := p.scan()
switch tok {
case scanner.WORD:
// Write word to current buffer
currentBuf.WriteString(lit)
case scanner.WS:
// Write whitespace to current buffer
currentBuf.WriteString(lit)
case scanner.PUNCT:
// If last literal is "]" and current is "("
if lastLit == "]" && lit == "(" {
// Set current buffer to source buffer
currentBuf = srcBuf
// Continue to next token
continue
}
// If last literal is ")" and current is "{"
if lastLit == ")" && lit == "{" {
// Set current buffer to link buffer
currentBuf = linkBuf
// Continue to next token
continue
}
// If current literal is "}" and current buffer is link buffer
if lit == "}" && currentBuf == linkBuf {
// Stop parsing
break parseLoop
}
// If literal does not contain any of the restrict characters
if !strings.ContainsAny(lit, "()[]{}") {
// Write literal to current buffer
currentBuf.WriteString(lit)
}
case scanner.EOL, scanner.EOF:
// Return nil as this is not a valid link
return nil
}
// Set last literal
lastLit = lit
}
// Set image properties
img.Alternate = altBuf.String()
img.Source = srcBuf.String()
img.Link = linkBuf.String()
return img
}