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 }