Commits

Ross Light committed 6b29250

Allow properties on block nodes

Comments (0)

Files changed (1)

 }
 
 func (s *scanner) parseBlockNode(indent, context int) {
-	initIndex := s.index
+	if s.tryBlockScalar(indent, context) {
+		return
+	}
 
-	// TODO: block-scalar
-	if s.trySeparate(indent+1, context) {
-		// TODO: properties
-		switch s.peek() {
-		case '|':
-			s.parseLiteral(indent)
-			return
-		case '>':
-			s.parseFolded(indent)
-			return
-		}
+	if s.tryBlockCollection(indent, context) {
+		return
 	}
-	s.index = initIndex
 
-	// block-collection
-	// TODO: properties
-	if s.trySLComments() {
-		if newIndent, ok := s.detectIndent(indent); ok {
-			indentIndex := s.index
-			s.acceptIndent(newIndent)
-			if s.peek() == '-' {
-				// block sequence
-				s.index = indentIndex
-				s.ignore()
-				s.parseBlockSequence(newIndent)
-				return
-			} else if s.peek() == '?' || s.peekImplicitKey() {
-				// block mapping
-				s.index = indentIndex
-				s.ignore()
-				s.parseBlockMapping(newIndent)
-				return
-			}
-		}
-	}
-	s.index = initIndex
-
-	// flow-in-block
+	// flow node
 	if !s.trySeparate(indent+1, flowOut) {
 		s.expected("space")
 	}
 	s.ignore()
 }
 
+func (s *scanner) tryBlockScalar(indent, context int) (ok bool) {
+	defer func(initIndex int) {
+		if !ok {
+			s.index = initIndex
+		}
+	}(s.index)
+
+	if !s.trySeparate(indent+1, context) {
+		return false
+	}
+
+	propIndex := s.index
+	props := s.tryProperties(indent+1, context)
+	if props != nil {
+		if !s.trySeparate(indent+1, context) {
+			s.index = propIndex
+			props = nil
+		}
+	}
+
+	r := s.peek()
+	if r != '|' && r != '>' {
+		return false
+	}
+
+	s.ignore()
+	for _, tok := range props {
+		s.tokens <- tok
+	}
+
+	switch r {
+	case '|':
+		s.parseLiteral(indent)
+	case '>':
+		s.parseFolded(indent)
+	}
+	return true
+}
+
 // Block scalar chomping indicators
 const (
 	chompClip  = 0
 	return
 }
 
+func (s *scanner) tryBlockCollection(indent, context int) (ok bool) {
+	defer func(initIndex int) {
+		if !ok {
+			s.index = initIndex
+		}
+	}(s.index)
+
+	var props []Token
+	if i := s.index; s.trySeparate(indent+1, context) {
+		if props = s.tryProperties(indent, context); props == nil {
+			s.index = i
+		}
+	}
+
+	if !s.trySLComments() {
+		return false
+	}
+
+	newIndent, ok := s.detectIndent(indent)
+	if !ok {
+		return false
+	}
+
+	indentIndex := s.index
+	s.acceptIndent(newIndent)
+	r := s.peek()
+	if r != '-' && r != '?' && !s.peekImplicitKey() {
+		return false
+	}
+
+	s.index = indentIndex
+	s.ignore()
+	for _, tok := range props {
+		s.tokens <- tok
+	}
+	if r == '-' {
+		s.parseBlockSequence(newIndent)
+	} else {
+		s.parseBlockMapping(newIndent)
+	}
+	return true
+}
+
 func (s *scanner) parseBlockSequence(indent int) {
 	s.emit(TokenBlockSequenceStart)