# Controlling YAML Flow Style vs Block Style Output in yaml-cpp: A Complete Guide

> Master YAML flow style vs block style output with yaml-cpp. Learn to control inline and multi-line formatting using YAML::Emitter and stream manipulators for precise YAML generation.

- Repository: [Jesse Beder/yaml-cpp](https://github.com/jbeder/yaml-cpp)
- Tags: how-to-guide
- Published: 2026-07-11

---

**yaml-cpp controls flow-style (inline) and block-style (multi-line) output through the `YAML::Emitter` class using stream manipulators (`YAML::Flow`, `YAML::Block`) and per-type format setters (`SetSeqFormat`, `SetMapFormat`).**

The yaml-cpp library (jbeder/yaml-cpp) provides precise control over YAML output formatting through its emitter subsystem. When generating YAML documents, you can choose between compact flow-style notation (`[1, 2, 3]`) or readable block-style indentation. This guide explains how to manipulate these styles using the library's official API based on the actual source implementation in [`src/emitter.cpp`](https://github.com/jbeder/yaml-cpp/blob/main/src/emitter.cpp) and related files.

## Understanding the Emitter Architecture

The `YAML::Emitter` class manages output generation through a **state stack** that tracks whether the current context uses block or flow formatting. According to the source code in [`src/emitter.cpp`](https://github.com/jbeder/yaml-cpp/blob/main/src/emitter.cpp), the emitter maintains this state in `EmitterState` and determines collection delimiters based on the current `flowType` value.

### How Context Switching Works

When you begin a collection using `BeginSeq` or `BeginMap`, the emitter calls `PrepareNode`, which forwards to specific preparation functions: `FlowSeqPrepareNode`, `BlockSeqPrepareNode`, `FlowMapPrepareNode`, or `BlockMapPrepareNode`. These functions consult the `flowType` stored in the emitter state and emit the appropriate delimiters (`[` and `]` for flow sequences, `{` and `}` for flow maps, or line breaks with indentation for block style).

## Temporary Style Control with Manipulators

**Manipulators** are special objects defined in [`include/yaml-cpp/emitterdef.h`](https://github.com/jbeder/yaml-cpp/blob/main/include/yaml-cpp/emitterdef.h) that modify the emitter's state when inserted into the stream. The most relevant manipulators for style control are `YAML::Flow` and `YAML::Block`.

### Applying Flow Style to Specific Collections

When you insert a manipulator immediately before `BeginSeq` or `BeginMap`, it forces that specific collection to render in the specified style. The manipulator affects only the next collection and automatically reverts to the previous context after the collection ends.

```cpp
#include <yaml-cpp/yaml.h>
#include <iostream>

int main() {
    YAML::Emitter out;
    out << YAML::BeginMap
        << YAML::Key << "title" << YAML::Value << "Example"
        << YAML::Key << "items"
        << YAML::Flow          // Force flow style for this sequence only
        << YAML::BeginSeq
        << "one" << "two" << "three"
        << YAML::EndSeq
        << YAML::EndMap;
    
    std::cout << out.c_str() << std::endl;
    // Output: title: Example
    //         items: [one, two, three]
}

```

### Scoped Block Style Application

Similarly, inserting `YAML::Block` before a collection forces multi-line formatting with proper indentation, even if the surrounding context uses flow style.

```cpp
YAML::Emitter out;
out << YAML::BeginSeq
    << "first"
    << YAML::Block        // Force block style for this nested map
    << YAML::BeginMap
      << YAML::Key << "nested" << YAML::Value << "value"
    << YAML::EndMap
    << "third"
    << YAML::EndSeq;

```

## Persistent Format Configuration with Setters

For global style control across multiple collections, the emitter exposes `SetSeqFormat(EMITTER_MANIP)` and `SetMapFormat(EMITTER_MANIP)`. These methods, implemented in [`include/yaml-cpp/emitter.h`](https://github.com/jbeder/yaml-cpp/blob/main/include/yaml-cpp/emitter.h), call `Emitter::SetLocalValue` to store the manipulator in the current `EmitterState`, affecting all subsequent collections of that type until changed again.

### Setting Default Sequence Format

```cpp
YAML::Emitter out;
out << YAML::SetSeqFormat(YAML::Flow);   // All following sequences use flow style
out << YAML::SetMapFormat(YAML::Block);  // All following maps use block style

out << YAML::BeginMap
    << YAML::Key << "list" << YAML::Value
    << YAML::BeginSeq << 1 << 2 << 3 << YAML::EndSeq  // Rendered as [1, 2, 3]
    << YAML::Key << "config"
    << YAML::BeginMap
      << YAML::Key << "enabled" << YAML::Value << true  // Rendered in block style
    << YAML::EndMap
    << YAML::EndMap;

```

## Practical Implementation Examples

### Mixed Style Documents

Combine flow and block styles within the same document to optimize readability:

```cpp
YAML::Emitter out;
out << YAML::BeginMap
    << YAML::Key << "name"  << YAML::Value << "Alice"
    << YAML::Key << "scores"
    << YAML::Flow           // Inline array for compactness
    << YAML::BeginSeq
    << 85 << 92 << 78
    << YAML::EndSeq
    << YAML::Key << "details"
    << YAML::BeginMap      // Block map for readability (default)
      << YAML::Key << "age"   << YAML::Value << 30
      << YAML::Key << "city"  << YAML::Value << "Paris"
    << YAML::EndMap
    << YAML::EndMap;
std::cout << out.c_str();

```

### Project-Wide Default Configuration

Set styles once at the emitter initialization for consistent formatting across your application:

```cpp
YAML::Emitter out;
out << YAML::SetSeqFormat(YAML::Flow)   // All sequences inline
    << YAML::SetMapFormat(YAML::Block); // All maps block-style

// All subsequent collections follow these rules until modified
out << YAML::BeginMap
    << YAML::Key << "data" << YAML::Value
    << YAML::BeginSeq << "a" << "b" << "c" << YAML::EndSeq
    << YAML::EndMap;

```

## Summary

- **Stream manipulators** (`YAML::Flow`, `YAML::Block`) provide temporary, scoped control over individual collections by setting the `flowType` in the emitter state immediately before `BeginSeq` or `BeginMap`.
- **Format setters** (`SetSeqFormat`, `SetMapFormat`) change the default style for all subsequent sequences or maps by modifying `EmitterState` through `SetLocalValue`.
- The implementation in [`src/emitter.cpp`](https://github.com/jbeder/yaml-cpp/blob/main/src/emitter.cpp) routes collection starts through specific preparation functions (`FlowSeqPrepareNode`, `BlockMapPrepareNode`, etc.) that emit the correct delimiters based on the current state.
- Styles automatically revert to the parent context after a collection ends, allowing fine-grained mixing of flow and block formats within nested structures.

## Frequently Asked Questions

### How long does a flow style manipulator remain active?

A manipulator like `YAML::Flow` applies only to the **immediately following** collection (`BeginSeq` or `BeginMap`). Once you call `EndSeq` or `EndMap`, the emitter reverts to the style defined by the parent context or the default settings. This scoping allows precise control without affecting sibling or parent nodes.

### What is the difference between manipulators and SetSeqFormat?

**Manipulators** (`YAML::Flow`, `YAML::Block`) affect only the next collection and are transient. **SetSeqFormat** and **SetMapFormat** modify the emitter's persistent local state, affecting all future collections of that type until you explicitly change the setting again or destroy the emitter. Use manipulators for one-off changes and setters for global defaults.

### Can I force block style for a specific map while keeping sequences in flow style?

Yes. You can mix styles arbitrarily by combining global defaults with local manipulators. For example, set `SetSeqFormat(YAML::Flow)` for all sequences, then insert `YAML::Block` immediately before any specific `BeginMap` that requires multi-line formatting. The manipulator overrides the global setting for that single collection.

### Where are the manipulator objects defined in the source code?

The manipulator constants are defined in [`include/yaml-cpp/emitterdef.h`](https://github.com/jbeder/yaml-cpp/blob/main/include/yaml-cpp/emitterdef.h), while the `YAML::Emitter` class that processes them is declared in [`include/yaml-cpp/emitter.h`](https://github.com/jbeder/yaml-cpp/blob/main/include/yaml-cpp/emitter.h). The logic that interprets these manipulators and selects output delimiters resides in [`src/emitter.cpp`](https://github.com/jbeder/yaml-cpp/blob/main/src/emitter.cpp), specifically within the `PrepareNode` family of functions and the `EmitterState` management code in [`src/emitterstate.cpp`](https://github.com/jbeder/yaml-cpp/blob/main/src/emitterstate.cpp).