code: func (s *Scanner) Scan() (Block, error) {
  	if err := s.init(); err != nil {
  		return nil, err
  	}
  
  	switch s.peek() {
  	case '<':
  		// Special handling for component/attr blocks.
  		if s.peekComponentStartBlock() {
  			return s.scanComponentStartBlock()
  		} else if s.peekComponentEndBlock() {
  			return s.scanComponentEndBlock()
  		} else if s.peekAttrStartBlock() {
  			return s.scanAttrStartBlock()
  		} else if s.peekAttrEndBlock() {
  			return s.scanAttrEndBlock()
  		}
  
  		// Special handling for ego blocks.
  		if s.peekN(4) == "<%==" {
  			return s.scanRawPrintBlock()
  		} else if s.peekN(3) == "<%=" {
  			return s.scanPrintBlock()
  		} else if s.peekN(2) == "<%" {
  			return s.scanCodeBlock()
  		}
  
  	case eof:
  		return nil, io.EOF
  	}
  	return s.scanTextBlock()
  }
docs: // Scan returns the next block from the reader.