docs: Cleanup indentation

- Remove accidental blockquotes around lists and code-blocks
- Reindent most directives to 3 spaces
- Add code-block:: proto where appropriate

Change-Id: I8b4e17c2a607b2cab042693304b9cc35f807b593
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/168537
Presubmit-Verified: CQ Bot Account <pigweed-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Wyatt Hepler <hepler@google.com>
Commit-Queue: Auto-Submit <auto-submit@pigweed-service-accounts.iam.gserviceaccount.com>
Pigweed-Auto-Submit: Anthony DiGirolamo <tonymd@google.com>
diff --git a/docs/build_system.rst b/docs/build_system.rst
index 549f003..ed54676 100644
--- a/docs/build_system.rst
+++ b/docs/build_system.rst
@@ -361,10 +361,10 @@
 * ``ubsan_heuristic`` -- `UndefinedBehaviorSanitizer`_ with the following
   additional checks enabled:
 
-   * ``integer``: Checks for undefined or suspicious integer behavior.
-   * ``float-divide-by-zero``: Checks for floating point division by zero.
-   * ``implicit-conversion``: Checks for suspicious behavior of implicit conversions.
-   * ``nullability``: Checks for null as function arg, lvalue and return type.
+  * ``integer``: Checks for undefined or suspicious integer behavior.
+  * ``float-divide-by-zero``: Checks for floating point division by zero.
+  * ``implicit-conversion``: Checks for suspicious behavior of implicit conversions.
+  * ``nullability``: Checks for null as function arg, lvalue and return type.
 
   These additional checks are heuristic and may not correspond to undefined
   behavior.
@@ -662,23 +662,23 @@
 
 1. Add the following lines to your '.bazelrc'.
 
-  .. code:: sh
+   .. code:: sh
 
-    coverage --experimental_generate_llvm_lcov
-    coverage --combined_report=lcov
+      coverage --experimental_generate_llvm_lcov
+      coverage --combined_report=lcov
 
 2. Generate a combined lcov coverage report. This will produce a combined lcov
    coverage report at the path 'bazel-out/_coverage/_coverage_report.dat'. e.g.
 
-  .. code:: sh
+   .. code:: sh
 
-    bazel coverage //pw_log/...
+      bazel coverage //pw_log/...
 
 3. View the results using the command line utility 'lcov'.
 
-  .. code:: sh
+   .. code:: sh
 
-    lcov --list bazel-out/_coverage/_coverage_report.dat
+      lcov --list bazel-out/_coverage/_coverage_report.dat
 
 Configuration
 -------------
@@ -821,16 +821,16 @@
 2. Add a pigweed_config rule to your WORKSPACE, using Pigweed's default
    configuration.
 
-  .. code:: py
+   .. code:: py
 
-    # WORKSPACE ...
-    load("//pw_build:target_config.bzl", "pigweed_config")
+      # WORKSPACE ...
+      load("//pw_build:target_config.bzl", "pigweed_config")
 
-    # Configure Pigweeds backend.
-    pigweed_config(
-        name = "pigweed_config",
-        build_file = "@pigweed//targets:default_config.BUILD",
-    )
+      # Configure Pigweeds backend.
+      pigweed_config(
+          name = "pigweed_config",
+          build_file = "@pigweed//targets:default_config.BUILD",
+      )
 
 .. note::
   We are aware, that the experience of setting up your WORKSPACE file to work
diff --git a/docs/embedded_cpp_guide.rst b/docs/embedded_cpp_guide.rst
index d5925b0..afe901a 100644
--- a/docs/embedded_cpp_guide.rst
+++ b/docs/embedded_cpp_guide.rst
@@ -117,14 +117,14 @@
 Pigweed compiles with a strict set of warnings. The warnings include the
 following:
 
-  * ``-Wall`` and ``-Wextra`` -- Standard sets of compilation warnings, which
-    are recommended for all projects.
-  * ``-Wimplicit-fallthrough`` -- Requires explicit ``[[fallthrough]]``
-    annotations for fallthrough between switch cases. Prevents unintentional
-    fallthroughs if a ``break`` or ``return`` is forgotten.
-  * ``-Wundef`` -- Requires macros to be defined before using them. This
-    disables the standard, problematic behavior that replaces undefined (or
-    misspelled) macros with ``0``.
+* ``-Wall`` and ``-Wextra`` -- Standard sets of compilation warnings, which
+  are recommended for all projects.
+* ``-Wimplicit-fallthrough`` -- Requires explicit ``[[fallthrough]]``
+  annotations for fallthrough between switch cases. Prevents unintentional
+  fallthroughs if a ``break`` or ``return`` is forgotten.
+* ``-Wundef`` -- Requires macros to be defined before using them. This
+  disables the standard, problematic behavior that replaces undefined (or
+  misspelled) macros with ``0``.
 
 Unused variable and function warnings
 -------------------------------------
@@ -133,46 +133,46 @@
 unused items. In some circumstances, these cannot be removed, so the warning
 must be silenced. This is done in one of the following ways:
 
-  1. When possible, delete unused variables, functions, or class definitions.
-  2. If an unused entity must remain in the code, avoid giving it a name. A
-     common situation that triggers unused parameter warnings is implementing a
-     virtual function or callback. In C++, function parameters may be unnamed.
-     If desired, the variable name can remain in the code as a comment.
+1. When possible, delete unused variables, functions, or class definitions.
+2. If an unused entity must remain in the code, avoid giving it a name. A
+   common situation that triggers unused parameter warnings is implementing a
+   virtual function or callback. In C++, function parameters may be unnamed.
+   If desired, the variable name can remain in the code as a comment.
 
-     .. code-block:: cpp
+   .. code-block:: cpp
 
-       class BaseCalculator {
-        public:
-         virtual int DoMath(int number_1, int number_2, int number_3) = 0;
-       };
+      class BaseCalculator {
+       public:
+        virtual int DoMath(int number_1, int number_2, int number_3) = 0;
+      };
 
-       class Calculator : public BaseCalculator {
-         int DoMath(int number_1, int /* number_2 */, int) override {
-           return number_1 * 100;
-         }
-       };
+      class Calculator : public BaseCalculator {
+        int DoMath(int number_1, int /* number_2 */, int) override {
+          return number_1 * 100;
+        }
+      };
 
-  3. In C++, annotate unused entities with `[[maybe_unused]]
-     <https://en.cppreference.com/w/cpp/language/attributes/maybe_unused>`_ to
-     silence warnings.
+3. In C++, annotate unused entities with `[[maybe_unused]]
+   <https://en.cppreference.com/w/cpp/language/attributes/maybe_unused>`_ to
+   silence warnings.
 
-     .. code-block:: cpp
+   .. code-block:: cpp
 
-       // This variable is unused in certain circumstances.
-       [[maybe_unused]] int expected_size = size * 4;
-       #if OPTION_1
-       DoThing1(expected_size);
-       #elif OPTION_2
-       DoThing2(expected_size);
-       #endif
+      // This variable is unused in certain circumstances.
+      [[maybe_unused]] int expected_size = size * 4;
+      #if OPTION_1
+      DoThing1(expected_size);
+      #elif OPTION_2
+      DoThing2(expected_size);
+      #endif
 
-  4. As a final option, cast unused variables to ``void`` to silence these
-     warnings. Use ``static_cast<void>(unused_var)`` in C++ or
-     ``(void)unused_var`` in C.
+4. As a final option, cast unused variables to ``void`` to silence these
+   warnings. Use ``static_cast<void>(unused_var)`` in C++ or
+   ``(void)unused_var`` in C.
 
-     In C, silencing warnings on unused functions may require compiler-specific
-     attributes (``__attribute__((unused))``). Avoid this by removing the
-     functions or compiling with C++ and using ``[[maybe_unused]]``.
+   In C, silencing warnings on unused functions may require compiler-specific
+   attributes (``__attribute__((unused))``). Avoid this by removing the
+   functions or compiling with C++ and using ``[[maybe_unused]]``.
 
 Dealing with ``nodiscard`` return values
 ----------------------------------------
@@ -183,8 +183,8 @@
 
 .. code-block:: cpp
 
-  // <tuple> defines std::ignore.
-  #include <tuple>
+   // <tuple> defines std::ignore.
+   #include <tuple>
 
-  DoThingWithStatus().IgnoreError();
-  std::ignore = DoThingWithReturnValue();
\ No newline at end of file
+   DoThingWithStatus().IgnoreError();
+   std::ignore = DoThingWithReturnValue();
diff --git a/docs/module_structure.rst b/docs/module_structure.rst
index c952ecc..26079db 100644
--- a/docs/module_structure.rst
+++ b/docs/module_structure.rst
@@ -13,97 +13,97 @@
 
 Example module structure
 ------------------------
-.. code-block:: python
+.. code-block:: text
 
-  pw_foo/...
+   pw_foo/...
 
-    docs.rst         # Docs landing page (required)
-    concepts.rst     # Conceptual docs (optional)
-    design.rst       # Design docs (optional)
-    guides.rst       # How-to guides (optional)
-    api.rst          # API reference (optional)
-    cli.rst          # CLI reference (optional)
-    gui.rst          # GUI reference (optional)
-    tutorials/*.rst  # Tutorials (optional)
+     docs.rst         # Docs landing page (required)
+     concepts.rst     # Conceptual docs (optional)
+     design.rst       # Design docs (optional)
+     guides.rst       # How-to guides (optional)
+     api.rst          # API reference (optional)
+     cli.rst          # CLI reference (optional)
+     gui.rst          # GUI reference (optional)
+     tutorials/*.rst  # Tutorials (optional)
 
-    BUILD.gn   # GN build required
-    BUILD      # Bazel build required
+     BUILD.gn   # GN build required
+     BUILD      # Bazel build required
 
-    # C++ public headers; the repeated module name is required
-    public/pw_foo/foo.h
-    public/pw_foo/baz.h
+     # C++ public headers; the repeated module name is required
+     public/pw_foo/foo.h
+     public/pw_foo/baz.h
 
-    # Exposed private headers go under internal/
-    public/pw_foo/internal/bar.h
-    public/pw_foo/internal/qux.h
+     # Exposed private headers go under internal/
+     public/pw_foo/internal/bar.h
+     public/pw_foo/internal/qux.h
 
-    # Public override headers must go in 'public_overrides'
-    public_overrides/gtest/gtest.h
-    public_overrides/string.h
+     # Public override headers must go in 'public_overrides'
+     public_overrides/gtest/gtest.h
+     public_overrides/string.h
 
-    # Private headers go into <module>_*/...
-    pw_foo_internal/zap.h
-    pw_foo_private/zip.h
-    pw_foo_secret/alxx.h
+     # Private headers go into <module>_*/...
+     pw_foo_internal/zap.h
+     pw_foo_private/zip.h
+     pw_foo_secret/alxx.h
 
-    # C++ implementations go in the root
-    foo_impl.cc
-    foo.cc
-    baz.cc
-    bar.cc
-    zap.cc
-    zip.cc
-    alxx.cc
+     # C++ implementations go in the root
+     foo_impl.cc
+     foo.cc
+     baz.cc
+     bar.cc
+     zap.cc
+     zip.cc
+     alxx.cc
 
-    # C++ tests also go in the root
-    foo_test.cc
-    bar_test.cc
-    zip_test.cc
+     # C++ tests also go in the root
+     foo_test.cc
+     bar_test.cc
+     zip_test.cc
 
-    # Python files go into 'py/<module>/...'
-    py/BUILD.gn     # Python packages are declared in GN using pw_python_package
-    py/setup.py     # Python files are structured as standard Python packages
-    py/foo_test.py  # Tests go in py/ but outside of the Python package
-    py/bar_test.py
-    py/pw_foo/__init__.py
-    py/pw_foo/__main__.py
-    py/pw_foo/bar.py
-    py/pw_foo/py.typed  # Indicates that this package has type annotations
+     # Python files go into 'py/<module>/...'
+     py/BUILD.gn     # Python packages are declared in GN using pw_python_package
+     py/setup.py     # Python files are structured as standard Python packages
+     py/foo_test.py  # Tests go in py/ but outside of the Python package
+     py/bar_test.py
+     py/pw_foo/__init__.py
+     py/pw_foo/__main__.py
+     py/pw_foo/bar.py
+     py/pw_foo/py.typed  # Indicates that this package has type annotations
 
-    # Rust crates go into 'rust/...'
-    rust/BUILD.bazel
-    rust/crate_one.rs          # Single file crates are in rust/<crate_name>.rs
-    rust/crate_two/lib.rs      # Multi-file crate's top level source in:
-                               #   rust/<crate>/lib.rs
-    rust/crate_two/mod_one.rs  # Multi-file crate's modules in:
-    rust/crate_two/mod_two.rs  #   rust/<crate>/<module_name>.rs
-                               # Prefer not using mod.rs files.
+     # Rust crates go into 'rust/...'
+     rust/BUILD.bazel
+     rust/crate_one.rs          # Single file crates are in rust/<crate_name>.rs
+     rust/crate_two/lib.rs      # Multi-file crate's top level source in:
+                                #   rust/<crate>/lib.rs
+     rust/crate_two/mod_one.rs  # Multi-file crate's modules in:
+     rust/crate_two/mod_two.rs  #   rust/<crate>/<module_name>.rs
+                                # Prefer not using mod.rs files.
 
-    # Go files go into 'go/...'
-    go/...
+     # Go files go into 'go/...'
+     go/...
 
-    # Examples go in examples/, mixing different languages
-    examples/demo.py
-    examples/demo.cc
-    examples/demo.go
-    examples/BUILD.gn
-    examples/BUILD
+     # Examples go in examples/, mixing different languages
+     examples/demo.py
+     examples/demo.cc
+     examples/demo.go
+     examples/BUILD.gn
+     examples/BUILD
 
-    # Size reports go under size_report/
-    size_report/BUILD.gn
-    size_report/base.cc
-    size_report/use_case_a.cc
-    size_report/use_case_b.cc
+     # Size reports go under size_report/
+     size_report/BUILD.gn
+     size_report/base.cc
+     size_report/use_case_a.cc
+     size_report/use_case_b.cc
 
-    # Protobuf definition files go into <module>_protos/...
-    pw_foo_protos/foo.proto
-    pw_foo_protos/internal/zap.proto
+     # Protobuf definition files go into <module>_protos/...
+     pw_foo_protos/foo.proto
+     pw_foo_protos/internal/zap.proto
 
-    # Other directories are fine, but should be private.
-    data/...
-    graphics/...
-    collection_of_tests/...
-    code_relating_to_subfeature/...
+     # Other directories are fine, but should be private.
+     data/...
+     graphics/...
+     collection_of_tests/...
+     code_relating_to_subfeature/...
 
 Module name
 -----------
@@ -133,10 +133,10 @@
 
 .. code-block::
 
-  pw_foo/...
-    public/pw_foo/foo.h
-    public/pw_foo/a_header.h
-    public/pw_foo/baz.h
+   pw_foo/...
+     public/pw_foo/foo.h
+     public/pw_foo/a_header.h
+     public/pw_foo/baz.h
 
 For headers that must be exposed due to C++ limitations (i.e. are included from
 the public interface, but are not intended for use), place the headers in a
@@ -475,7 +475,7 @@
 
 10. Add the new module to CMake build
 
-   - In ``/CMakeLists.txt`` add ``add_subdirectory(pw_new)``
+    - In ``/CMakeLists.txt`` add ``add_subdirectory(pw_new)``
 
 11. Run :ref:`module-pw_module-module-check`
 
diff --git a/docs/style_guide.rst b/docs/style_guide.rst
index f61e9df..a732647 100644
--- a/docs/style_guide.rst
+++ b/docs/style_guide.rst
@@ -859,11 +859,11 @@
 #. Groups are placed the following order with a blank line separating each
    grouping.
 
-    * "set noparent" line
-    * "include" lines
-    * "file:" lines
-    * user grants (some examples: "*", "foo@example.com")
-    * "per-file:" lines
+   * "set noparent" line
+   * "include" lines
+   * "file:" lines
+   * user grants (some examples: "*", "foo@example.com")
+   * "per-file:" lines
 
 This plugin will, by default, act upon any file named "OWNERS".
 
diff --git a/pw_assert_tokenized/docs.rst b/pw_assert_tokenized/docs.rst
index 2458b5a..bb3d8f8 100644
--- a/pw_assert_tokenized/docs.rst
+++ b/pw_assert_tokenized/docs.rst
@@ -18,16 +18,20 @@
   number of the assert statement. By default, it is passed to the logging system
   to produce a string like this:
 
-    PW_ASSERT() or PW_DASSERT() failure at
-    pw_result/public/pw_result/result.h:63
+  .. code-block:: text
+
+     PW_ASSERT() or PW_DASSERT() failure at
+     pw_result/public/pw_result/result.h:63
 
 * **PW_CHECK_\*()**: The ``PW_CHECK_*()`` macros work in contexts where
   tokenization is fully supported, so they are able to capture the CHECK
   statement expression and any provided string literal in addition to the file
   name in the pw_log_tokenized key/value format:
 
-    "■msg♦Check failure: \*unoptimizable >= 0, Ensure this CHECK logic
-    stays■module♦KVS■file♦pw_kvs/size_report/base.cc"
+  .. code-block:: text
+
+     "■msg♦Check failure: \*unoptimizable >= 0, Ensure this CHECK logic
+     stays■module♦KVS■file♦pw_kvs/size_report/base.cc"
 
   Evaluated values of ``PW_CHECK_*()`` statements are not captured, and any
   string formatting arguments are also not captured. This minimizes call-site
diff --git a/pw_blob_store/docs.rst b/pw_blob_store/docs.rst
index 57f211f..e881014 100644
--- a/pw_blob_store/docs.rst
+++ b/pw_blob_store/docs.rst
@@ -47,15 +47,15 @@
 
 .. code-block:: cpp
 
-  BlobStore::BlobWriterWithBuffer writer(my_blob_store);
-  writer.Open();
-  writer.Write(my_data);
+   BlobStore::BlobWriterWithBuffer writer(my_blob_store);
+   writer.Open();
+   writer.Write(my_data);
 
-  // ...
+   // ...
 
-  // A close is implied when a BlobWriter is destroyed. Manually closing a
-  // BlobWriter enables error handling on Close() failure.
-  writer.Close();
+   // A close is implied when a BlobWriter is destroyed. Manually closing a
+   // BlobWriter enables error handling on Close() failure.
+   writer.Close();
 
 Erasing a BlobStore
 ===================
@@ -83,13 +83,13 @@
 
 .. code-block:: cpp
 
-  constexpr size_t kMaxFileNameLength = 48;
-  BlobStore::BlobWriterWithBuffer<kMaxFileNameLength> writer(my_blob_store);
-  writer.Open();
-  writer.SetFileName("stonks.jpg");
-  writer.Write(my_data);
-  // ...
-  writer.Close();
+   constexpr size_t kMaxFileNameLength = 48;
+   BlobStore::BlobWriterWithBuffer<kMaxFileNameLength> writer(my_blob_store);
+   writer.Open();
+   writer.SetFileName("stonks.jpg");
+   writer.Write(my_data);
+   // ...
+   writer.Close();
 
 Reading from a BlobStore
 ------------------------
@@ -97,12 +97,12 @@
 readers/writers may be open/active if a ``BlobWriter`` is opened on a blob
 store.
 
-  0) Create BlobReader instance
-  1) BlobReader::Open()
-  2) Read data using BlobReader::Read() or
-     BlobReader::GetMemoryMappedBlob(). BlobReader is seekable. Use
-     BlobReader::Seek() to read from a desired offset.
-  3) BlobReader::Close()
+0) Create BlobReader instance
+1) BlobReader::Open()
+2) Read data using BlobReader::Read() or
+   BlobReader::GetMemoryMappedBlob(). BlobReader is seekable. Use
+   BlobReader::Seek() to read from a desired offset.
+3) BlobReader::Close()
 
 --------------------------
 FileSystem RPC integration
@@ -119,6 +119,5 @@
 
 .. include:: blob_size
 
-
 .. note::
   The documentation for this module is currently incomplete.
diff --git a/pw_bluetooth_hci/docs.rst b/pw_bluetooth_hci/docs.rst
index 863be7c..2d8744a 100644
--- a/pw_bluetooth_hci/docs.rst
+++ b/pw_bluetooth_hci/docs.rst
@@ -31,24 +31,25 @@
 A decoder function is provided to parse HCI packets out of a HCI UART Transport
 Layer buffer which may contain multiple packets.
 
-  .. cpp:function:: StatusWithSize DecodeHciUartData(ConstByteSpan data, const DecodedPacketCallback& packet_callback);
+.. cpp:function:: StatusWithSize DecodeHciUartData(ConstByteSpan data, const DecodedPacketCallback& packet_callback);
 
-    Parses the HCI Packets out of a HCI UART Transport Layer buffer.
+   Parses the HCI Packets out of a HCI UART Transport Layer buffer.
 
-    Parses as many complete HCI packets out of the provided buffer based on the
-    HCI UART Transport Layer as defined by Bluetooth Core Specification version
-    5.3 "Host Controller Interface Transport Layer" volume 4, part A.
+   Parses as many complete HCI packets out of the provided buffer based on the
+   HCI UART Transport Layer as defined by Bluetooth Core Specification version
+   5.3 "Host Controller Interface Transport Layer" volume 4, part A.
 
-    The HciPacketCallback is invoked for each full HCI packet.
+   The HciPacketCallback is invoked for each full HCI packet.
 
-    Returns the number of bytes processed and a status based on:
+   Returns the number of bytes processed and a status based on:
 
-      * OK - No invalid packet indicator found.
-      * DATA_LOSS - An invalid packet indicator was detected between packets.
-        Synchronization has been lost. The caller is responsible for
-        regaining synchronization
+   * OK - No invalid packet indicator found.
+   * DATA_LOSS - An invalid packet indicator was detected between packets.
+     Synchronization has been lost. The caller is responsible for
+     regaining synchronization
 
-    .. note:: The caller is responsible for detecting the lack of progress due
-      to an undersized data buffer and/or an invalid length field in case a full
+   .. note::
+      The caller is responsible for detecting the lack of progress due to an
+      undersized data buffer and/or an invalid length field in case a full
       buffer is passed and no bytes are processed.
 
diff --git a/pw_build/gn.rst b/pw_build/gn.rst
index 86944d5..e38ffef 100644
--- a/pw_build/gn.rst
+++ b/pw_build/gn.rst
@@ -38,11 +38,11 @@
 ------------
 .. code-block::
 
-  import("$dir_pw_build/target_types.gni")
+   import("$dir_pw_build/target_types.gni")
 
-  pw_source_set("my_library") {
-    sources = [ "lib.cc" ]
-  }
+   pw_source_set("my_library") {
+     sources = [ "lib.cc" ]
+   }
 
 Pigweed defines wrappers around the four basic GN binary types ``source_set``,
 ``executable``, ``static_library``, and ``shared_library``. These templates
@@ -170,9 +170,9 @@
 To add or update GN build files for libraries that only offer Bazel build files,
 the Python script at ``pw_build/py/pw_build/generate_3p_gn.py`` may be used.
 
-  .. note::
-    The ``generate_3p_gn.py`` script is experimental, and may not work on an
-    arbitrary Bazel library.
+.. note::
+   The ``generate_3p_gn.py`` script is experimental, and may not work on an
+   arbitrary Bazel library.
 
 To generate or update the GN offered by Pigweed from an Bazel upstream project,
 first create a ``third_party/<library>/repo.json`` file. This file should
diff --git a/pw_checksum/docs.rst b/pw_checksum/docs.rst
index aa9a0a8..fcec3be 100644
--- a/pw_checksum/docs.rst
+++ b/pw_checksum/docs.rst
@@ -124,7 +124,7 @@
 
 Dependencies
 ============
-* ``pw_span``
+- :ref:`module-pw_span`
 
 .. _Module Configuration Options:
 
diff --git a/pw_cli/docs.rst b/pw_cli/docs.rst
index 4ab1715..1f33612 100644
--- a/pw_cli/docs.rst
+++ b/pw_cli/docs.rst
@@ -293,50 +293,50 @@
 
 Plugins may be registered in a few different ways.
 
- * **Direct function call.** Register plugins by calling
-   :py:meth:`pw_cli.plugins.Registry.register` or
-   :py:meth:`pw_cli.plugins.Registry.register_by_name`.
+* **Direct function call.** Register plugins by calling
+  :py:meth:`pw_cli.plugins.Registry.register` or
+  :py:meth:`pw_cli.plugins.Registry.register_by_name`.
 
-   .. code-block:: python
+  .. code-block:: python
 
-     registry = pw_cli.plugins.Registry()
+    registry = pw_cli.plugins.Registry()
 
-     registry.register('plugin_name', my_plugin)
-     registry.register_by_name('plugin_name', 'module_name', 'function_name')
+    registry.register('plugin_name', my_plugin)
+    registry.register_by_name('plugin_name', 'module_name', 'function_name')
 
- * **Decorator.** Register using the :py:meth:`pw_cli.plugins.Registry.plugin`
-   decorator.
+* **Decorator.** Register using the :py:meth:`pw_cli.plugins.Registry.plugin`
+  decorator.
 
-   .. code-block:: python
+  .. code-block:: python
 
-     _REGISTRY = pw_cli.plugins.Registry()
+    _REGISTRY = pw_cli.plugins.Registry()
 
-     # This function is registered as the "my_plugin" plugin.
-     @_REGISTRY.plugin
-     def my_plugin():
-         pass
+    # This function is registered as the "my_plugin" plugin.
+    @_REGISTRY.plugin
+    def my_plugin():
+        pass
 
-     # This function is registered as the "input" plugin.
-     @_REGISTRY.plugin(name='input')
-     def read_something():
-         pass
+    # This function is registered as the "input" plugin.
+    @_REGISTRY.plugin(name='input')
+    def read_something():
+        pass
 
-   The decorator may be aliased to give a cleaner syntax (e.g. ``register =
-   my_registry.plugin``).
+  The decorator may be aliased to give a cleaner syntax (e.g. ``register =
+  my_registry.plugin``).
 
- * **Plugins files.** Plugins files use a simple format:
+* **Plugins files.** Plugins files use a simple format:
 
-   .. code-block::
+  .. code-block::
 
-     # Comments start with "#". Blank lines are ignored.
-     name_of_the_plugin module.name module_member
+    # Comments start with "#". Blank lines are ignored.
+    name_of_the_plugin module.name module_member
 
-     another_plugin some_module some_function
+    another_plugin some_module some_function
 
-   These files are placed in the file system and apply similarly to Git's
-   ``.gitignore`` files. From Python, these files are registered using
-   :py:meth:`pw_cli.plugins.Registry.register_file` and
-   :py:meth:`pw_cli.plugins.Registry.register_directory`.
+  These files are placed in the file system and apply similarly to Git's
+  ``.gitignore`` files. From Python, these files are registered using
+  :py:meth:`pw_cli.plugins.Registry.register_file` and
+  :py:meth:`pw_cli.plugins.Registry.register_directory`.
 
 pw_cli.plugins module reference
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/pw_cpu_exception/docs.rst b/pw_cpu_exception/docs.rst
index 0cd2140..b3a154e 100644
--- a/pw_cpu_exception/docs.rst
+++ b/pw_cpu_exception/docs.rst
@@ -39,12 +39,12 @@
 ``pw_cpu_exception_DefaultHandler()``. The behavior of this functions is entirely
 up to the application/project, but some examples are provided below:
 
-  * Enter an infinite loop so the device can be debugged by JTAG.
-  * Reset the device.
-  * Attempt to handle the exception so execution can continue.
-  * Capture and record additional device state and save to flash for a crash
-    report.
-  * A combination of the above, using logic that fits the needs of your project.
+* Enter an infinite loop so the device can be debugged by JTAG.
+* Reset the device.
+* Attempt to handle the exception so execution can continue.
+* Capture and record additional device state and save to flash for a crash
+  report.
+* A combination of the above, using logic that fits the needs of your project.
 
 ``pw_cpu_exception_SUPPORT_BACKEND``
 ====================================
@@ -102,22 +102,20 @@
 mechanisms to capture CPU state for use by an application's exception handler,
 and allow recovery from CPU exceptions when possible.
 
-  * The entry backend should provide a definition for the
-    ``pw_cpu_exception_State`` object through
-    ``pw_cpu_exception_backend/state.h``.
-  * In GN, the entry backend should also provide a ``.impl`` suffixed form of
-    the entry backend target which collects the actual entry implementation to
-    avoid circular dependencies due to the state definition in the entry backend
-    target.
-  * The entry backend should implement the ``pw_cpu_exception_Entry()`` function
-    that will call ``pw_cpu_exception_HandleException()`` after performing any
-    necessary actions prior to handing control to the application's exception
-    handler (e.g. capturing necessary CPU state).
-  * If an application's exception handler backend modifies the captured CPU
-    state, the state should be treated as though it were the original state of
-    the CPU when the exception occurred. The backend may need to manually
-    restore some of the modified state to ensure this on exception handler
-    return.
+* The entry backend should provide a definition for the
+  ``pw_cpu_exception_State`` object through
+  ``pw_cpu_exception_backend/state.h``.
+* In GN, the entry backend should also provide a ``.impl`` suffixed form of the
+  entry backend target which collects the actual entry implementation to avoid
+  circular dependencies due to the state definition in the entry backend target.
+* The entry backend should implement the ``pw_cpu_exception_Entry()`` function
+  that will call ``pw_cpu_exception_HandleException()`` after performing any
+  necessary actions prior to handing control to the application's exception
+  handler (e.g. capturing necessary CPU state).
+* If an application's exception handler backend modifies the captured CPU state,
+  the state should be treated as though it were the original state of the CPU
+  when the exception occurred. The backend may need to manually restore some of
+  the modified state to ensure this on exception handler return.
 
 -------------
 Compatibility
@@ -128,5 +126,5 @@
 ------------
 Dependencies
 ------------
-  * ``pw_span``
-  * ``pw_preprocessor``
+- :ref:`module-pw_span`
+- :ref:`module-pw_preprocessor`
diff --git a/pw_cpu_exception_cortex_m/docs.rst b/pw_cpu_exception_cortex_m/docs.rst
index b8726b2..b52e17e 100644
--- a/pw_cpu_exception_cortex_m/docs.rst
+++ b/pw_cpu_exception_cortex_m/docs.rst
@@ -15,60 +15,63 @@
 There are a few ways to set up the Cortex M exception handler so the
 application's exception handler is properly called during an exception.
 
-**1. Use existing CMSIS functions**
-  Inside of CMSIS fault handler functions, branch to ``pw_cpu_exception_Entry``.
+1. Use existing CMSIS functions
+-------------------------------
+Inside of CMSIS fault handler functions, branch to ``pw_cpu_exception_Entry``.
 
-  .. code-block:: cpp
+.. code-block:: cpp
 
-    __attribute__((naked)) void HardFault_Handler(void) {
-    asm volatile(
-        " ldr r0, =pw_cpu_exception_Entry  \n"
-        " bx r0                            \n");
-    }
+   __attribute__((naked)) void HardFault_Handler(void) {
+   asm volatile(
+       " ldr r0, =pw_cpu_exception_Entry  \n"
+       " bx r0                            \n");
+   }
 
-**2. Modify a startup file**
-  Assembly startup files for some microcontrollers initialize the interrupt
-  vector table. The functions to call for fault handlers can be changed here.
-  For ARMv7-M and ARMv8-M, the fault handlers are indexes 3 to 6 of the
-  interrupt vector table. It's also may be helpful to redirect the NMI handler
-  to the entry function (if it's otherwise unused in your project).
+2. Modify a startup file
+------------------------
+Assembly startup files for some microcontrollers initialize the interrupt
+vector table. The functions to call for fault handlers can be changed here.
+For ARMv7-M and ARMv8-M, the fault handlers are indexes 3 to 6 of the
+interrupt vector table. It's also may be helpful to redirect the NMI handler
+to the entry function (if it's otherwise unused in your project).
 
-  Default:
+Default:
 
-  .. code-block:: cpp
+.. code-block:: cpp
 
-    __isr_vector_table:
-      .word  __stack_start
-      .word  Reset_Handler
-      .word  NMI_Handler
-      .word  HardFault_Handler
-      .word  MemManage_Handler
-      .word  BusFault_Handler
-      .word  UsageFault_Handler
+   __isr_vector_table:
+     .word  __stack_start
+     .word  Reset_Handler
+     .word  NMI_Handler
+     .word  HardFault_Handler
+     .word  MemManage_Handler
+     .word  BusFault_Handler
+     .word  UsageFault_Handler
 
-  Using CPU exception module:
+Using CPU exception module:
 
-  .. code-block:: cpp
+.. code-block:: cpp
 
-    __isr_vector_table:
-      .word  __stack_start
-      .word  Reset_Handler
-      .word  pw_cpu_exception_Entry
-      .word  pw_cpu_exception_Entry
-      .word  pw_cpu_exception_Entry
-      .word  pw_cpu_exception_Entry
-      .word  pw_cpu_exception_Entry
+   __isr_vector_table:
+     .word  __stack_start
+     .word  Reset_Handler
+     .word  pw_cpu_exception_Entry
+     .word  pw_cpu_exception_Entry
+     .word  pw_cpu_exception_Entry
+     .word  pw_cpu_exception_Entry
+     .word  pw_cpu_exception_Entry
 
-  Note: ``__isr_vector_table`` and ``__stack_start`` are example names, and may
-  vary by platform. See your platform's assembly startup script.
+Note: ``__isr_vector_table`` and ``__stack_start`` are example names, and may
+vary by platform. See your platform's assembly startup script.
 
-**3. Modify interrupt vector table at runtime**
-  Some applications may choose to modify their interrupt vector tables at
-  runtime. The exception handler works with this use case (see the
-  exception_entry_test integration test), but keep in mind that your
-  application's exception handler will not be entered if an exception occurs
-  before the vector table entries are updated to point to
-  ``pw_cpu_exception_Entry``.
+3. Modify interrupt vector table at runtime
+-------------------------------------------
+Some applications may choose to modify their interrupt vector tables at
+runtime. The exception handler works with this use case (see the
+exception_entry_test integration test), but keep in mind that your
+application's exception handler will not be entered if an exception occurs
+before the vector table entries are updated to point to
+``pw_cpu_exception_Entry``.
 
 Module Usage
 ============
@@ -115,7 +118,6 @@
 
 Configuration Options
 =====================
-
 - ``PW_CPU_EXCEPTION_CORTEX_M_EXTENDED_CFSR_DUMP``: Enable extended logging in
   ``pw::cpu_exception::LogCpuState()`` that dumps the active CFSR fields with
   help strings. This is disabled by default since it increases the binary size
@@ -139,30 +141,30 @@
 
 For example:
 
-  .. code-block::
+.. code-block::
 
-    $ python -m pw_cpu_exception_cortex_m.cfsr_decoder 0x00010100
-    20210412 15:11:14 INF Exception caused by a usage fault, bus fault.
+   $ python -m pw_cpu_exception_cortex_m.cfsr_decoder 0x00010100
+   20210412 15:11:14 INF Exception caused by a usage fault, bus fault.
 
-    Active Crash Fault Status Register (CFSR) fields:
-    IBUSERR     Instruction bus error.
-        The processor attempted to issue an invalid instruction. It
-        detects the instruction bus error on prefecting, but this
-        flag is only set to 1 if it attempts to issue the faulting
-        instruction. When this bit is set, the processor has not
-        written a fault address to the BFAR.
-    UNDEFINSTR  Encountered invalid instruction.
-        The processor has attempted to execute an undefined
-        instruction. When this bit is set to 1, the PC value stacked
-        for the exception return points to the undefined instruction.
-        An undefined instruction is an instruction that the processor
-        cannot decode.
+   Active Crash Fault Status Register (CFSR) fields:
+   IBUSERR     Instruction bus error.
+       The processor attempted to issue an invalid instruction. It
+       detects the instruction bus error on prefecting, but this
+       flag is only set to 1 if it attempts to issue the faulting
+       instruction. When this bit is set, the processor has not
+       written a fault address to the BFAR.
+   UNDEFINSTR  Encountered invalid instruction.
+       The processor has attempted to execute an undefined
+       instruction. When this bit is set to 1, the PC value stacked
+       for the exception return points to the undefined instruction.
+       An undefined instruction is an instruction that the processor
+       cannot decode.
 
-    All registers:
-    cfsr       0x00010100
+   All registers:
+   cfsr       0x00010100
 
 .. note::
-  The CFSR is not supported on ARMv6-M CPUs (Cortex M0, M0+, M1).
+   The CFSR is not supported on ARMv6-M CPUs (Cortex M0, M0+, M1).
 
 --------------------
 Snapshot integration
@@ -186,10 +188,10 @@
 information is captured by a ``pw::thread::Thread`` protobuf encoder.
 
 .. note::
-  We recommend providing the ``pw_cpu_exception_State``, for example through
-  ``pw_cpu_exception_DefaultHandler()`` instead of using the current running
-  context to capture the main stack to minimize how much of the snapshot
-  handling is captured in the stack.
+   We recommend providing the ``pw_cpu_exception_State``, for example through
+   ``pw_cpu_exception_DefaultHandler()`` instead of using the current running
+   context to capture the main stack to minimize how much of the snapshot
+   handling is captured in the stack.
 
 Python processor
 ================
@@ -199,43 +201,43 @@
 
 .. code-block::
 
-  Exception caused by a usage fault.
+   Exception caused by a usage fault.
 
-  Active Crash Fault Status Register (CFSR) fields:
-  UNDEFINSTR  Undefined Instruction UsageFault.
-      The processor has attempted to execute an undefined
-      instruction. When this bit is set to 1, the PC value stacked
-      for the exception return points to the undefined instruction.
-      An undefined instruction is an instruction that the processor
-      cannot decode.
+   Active Crash Fault Status Register (CFSR) fields:
+   UNDEFINSTR  Undefined Instruction UsageFault.
+       The processor has attempted to execute an undefined
+       instruction. When this bit is set to 1, the PC value stacked
+       for the exception return points to the undefined instruction.
+       An undefined instruction is an instruction that the processor
+       cannot decode.
 
-  All registers:
-  pc         0x0800e1c4 example::Service::Crash(_example_service_CrashRequest const&, _pw_protobuf_Empty&) (src/example_service/service.cc:131)
-  lr         0x0800e141 example::Service::Crash(_example_service_CrashRequest const&, _pw_protobuf_Empty&) (src/example_service/service.cc:128)
-  psr        0x81000000
-  msp        0x20040fd8
-  psp        0x20001488
-  exc_return 0xffffffed
-  cfsr       0x00010000
-  mmfar      0xe000ed34
-  bfar       0xe000ed38
-  icsr       0x00000803
-  hfsr       0x40000000
-  shcsr      0x00000000
-  control    0x00000000
-  r0         0xe03f7847
-  r1         0x714083dc
-  r2         0x0b36dc49
-  r3         0x7fbfbe1a
-  r4         0xc36e8efb
-  r5         0x69a14b13
-  r6         0x0ec35eaa
-  r7         0xa5df5543
-  r8         0xc892b931
-  r9         0xa2372c94
-  r10        0xbd15c968
-  r11        0x759b95ab
-  r12        0x00000000
+   All registers:
+   pc         0x0800e1c4 example::Service::Crash(_example_service_CrashRequest const&, _pw_protobuf_Empty&) (src/example_service/service.cc:131)
+   lr         0x0800e141 example::Service::Crash(_example_service_CrashRequest const&, _pw_protobuf_Empty&) (src/example_service/service.cc:128)
+   psr        0x81000000
+   msp        0x20040fd8
+   psp        0x20001488
+   exc_return 0xffffffed
+   cfsr       0x00010000
+   mmfar      0xe000ed34
+   bfar       0xe000ed38
+   icsr       0x00000803
+   hfsr       0x40000000
+   shcsr      0x00000000
+   control    0x00000000
+   r0         0xe03f7847
+   r1         0x714083dc
+   r2         0x0b36dc49
+   r3         0x7fbfbe1a
+   r4         0xc36e8efb
+   r5         0x69a14b13
+   r6         0x0ec35eaa
+   r7         0xa5df5543
+   r8         0xc892b931
+   r9         0xa2372c94
+   r10        0xbd15c968
+   r11        0x759b95ab
+   r12        0x00000000
 
 Module Configuration Options
 ============================
@@ -246,17 +248,17 @@
 
 .. c:macro:: PW_CPU_EXCEPTION_CORTEX_M_LOG_LEVEL
 
-  The log level to use for this module. Logs below this level are omitted.
+   The log level to use for this module. Logs below this level are omitted.
 
-  This defaults to ``PW_LOG_LEVEL_DEBUG``.
+   This defaults to ``PW_LOG_LEVEL_DEBUG``.
 
 .. c:macro:: PW_CPU_EXCEPTION_CORTEX_M_EXTENDED_CFSR_DUMP
 
-  Enables extended logging in pw::cpu_exception::LogCpuState() and
-  pw::cpu_exception::cortex_m::LogExceptionAnalysis() that dumps the active
-  CFSR fields with help strings. This is disabled by default since it
-  increases the binary size by >1.5KB when using plain-text logs, or ~460
-  Bytes when using tokenized logging. It's useful to enable this for device
-  bringup until your application has an end-to-end crash reporting solution.
+   Enables extended logging in pw::cpu_exception::LogCpuState() and
+   pw::cpu_exception::cortex_m::LogExceptionAnalysis() that dumps the active
+   CFSR fields with help strings. This is disabled by default since it
+   increases the binary size by >1.5KB when using plain-text logs, or ~460
+   Bytes when using tokenized logging. It's useful to enable this for device
+   bringup until your application has an end-to-end crash reporting solution.
 
-  This is disabled by default.
+   This is disabled by default.
diff --git a/pw_function/docs.rst b/pw_function/docs.rst
index 18041ef..bd774b6 100644
--- a/pw_function/docs.rst
+++ b/pw_function/docs.rst
@@ -23,36 +23,36 @@
 
 .. code-block:: c++
 
-  int Add(int a, int b) { return a + b; }
+   int Add(int a, int b) { return a + b; }
 
-  // Construct a Function object from a function pointer.
-  pw::Function<int(int, int)> add_function(Add);
+   // Construct a Function object from a function pointer.
+   pw::Function<int(int, int)> add_function(Add);
 
-  // Invoke the function object.
-  int result = add_function(3, 5);
-  EXPECT_EQ(result, 8);
+   // Invoke the function object.
+   int result = add_function(3, 5);
+   EXPECT_EQ(result, 8);
 
-  // Construct a function from a lambda.
-  pw::Function<int(int)> negate([](int value) { return -value; });
-  EXPECT_EQ(negate(27), -27);
+   // Construct a function from a lambda.
+   pw::Function<int(int)> negate([](int value) { return -value; });
+   EXPECT_EQ(negate(27), -27);
 
 Functions are nullable. Invoking a null function triggers a runtime assert.
 
 .. code-block:: c++
 
-  // A function initialized without a callable is implicitly null.
-  pw::Function<void()> null_function;
+   // A function initialized without a callable is implicitly null.
+   pw::Function<void()> null_function;
 
-  // Null functions may also be explicitly created or set.
-  pw::Function<void()> explicit_null_function(nullptr);
+   // Null functions may also be explicitly created or set.
+   pw::Function<void()> explicit_null_function(nullptr);
 
-  pw::Function<void()> function([]() {});  // Valid (non-null) function.
-  function = nullptr;  // Set to null, clearing the stored callable.
+   pw::Function<void()> function([]() {});  // Valid (non-null) function.
+   function = nullptr;  // Set to null, clearing the stored callable.
 
-  // Functions are comparable to nullptr.
-  if (function != nullptr) {
-    function();
-  }
+   // Functions are comparable to nullptr.
+   if (function != nullptr) {
+     function();
+   }
 
 :cpp:type:`pw::Function`'s default constructor is ``constexpr``, so
 default-constructed functions may be used in classes with ``constexpr``
@@ -60,16 +60,16 @@
 
 .. code-block:: c++
 
-  class MyClass {
-   public:
-    // Default construction of a pw::Function is constexpr.
-    constexpr MyClass() { ... }
+   class MyClass {
+    public:
+     // Default construction of a pw::Function is constexpr.
+     constexpr MyClass() { ... }
 
-    pw::Function<void(int)> my_function;
-  };
+     pw::Function<void(int)> my_function;
+   };
 
-  // pw::Function and classes that use it may be constant initialized.
-  constinit MyClass instance;
+   // pw::Function and classes that use it may be constant initialized.
+   constinit MyClass instance;
 
 Storage
 =======
@@ -88,36 +88,37 @@
 
 .. admonition:: Inline storage size
 
-  The default inline size of two pointers is sufficient to store most common
-  callable objects, including function pointers, simple non-capturing and
-  capturing lambdas, and lightweight custom classes.
+   The default inline size of two pointers is sufficient to store most common
+   callable objects, including function pointers, simple non-capturing and
+   capturing lambdas, and lightweight custom classes.
 
 .. code-block:: c++
 
-  // The lambda is moved into the function's internal storage.
-  pw::Function<int(int, int)> subtract([](int a, int b) { return a - b; });
+   // The lambda is moved into the function's internal storage.
+   pw::Function<int(int, int)> subtract([](int a, int b) { return a - b; });
 
-  // Functions can be also be constructed from custom classes that implement
-  // operator(). This particular object is large (8 ints of space).
-  class MyCallable {
-   public:
-    int operator()(int value);
+   // Functions can be also be constructed from custom classes that implement
+   // operator(). This particular object is large (8 ints of space).
+   class MyCallable {
+    public:
+     int operator()(int value);
 
-   private:
-    int data_[8];
-  };
+    private:
+     int data_[8];
+   };
 
-  // Compiler error: sizeof(MyCallable) exceeds function's inline storage size.
-  pw::Function<int(int)> function((MyCallable()));
+   // Compiler error: sizeof(MyCallable) exceeds function's inline storage size.
+   pw::Function<int(int)> function((MyCallable()));
 
 .. admonition:: Dynamic allocation
 
-  When ``PW_FUNCTION_ENABLE_DYNAMIC_ALLOCATION`` is enabled, a ``Function``
-  will use dynamic allocation to store callables that exceed the inline size.
-  When it is enabled but a compile-time check for the inlining is still required
-  ``pw::InlineFunction`` can be used.
+   When ``PW_FUNCTION_ENABLE_DYNAMIC_ALLOCATION`` is enabled, a ``Function``
+   will use dynamic allocation to store callables that exceed the inline size.
+   When it is enabled but a compile-time check for the inlining is still required
+   ``pw::InlineFunction`` can be used.
 
 .. warning::
+
    If ``PW_FUNCTION_ENABLE_DYNAMIC_ALLOCATION`` is enabled then attempts to cast
    from `:cpp:type:`pw::InlineFunction` to a regular :cpp:type:`pw::Function`
    will **ALWAYS** allocate memory.
@@ -140,12 +141,12 @@
 
 .. code-block:: c++
 
-  // Before:
-  void DoTheThing(int arg, void (*callback)(int result));
+   // Before:
+   void DoTheThing(int arg, void (*callback)(int result));
 
-  // After. Note that it is possible to have parameter names within the function
-  // signature template for clarity.
-  void DoTheThing(int arg, const pw::Function<void(int result)>& callback);
+   // After. Note that it is possible to have parameter names within the function
+   // signature template for clarity.
+   void DoTheThing(int arg, const pw::Function<void(int result)>& callback);
 
 :cpp:type:`pw::Function` is movable, but not copyable, so APIs must accept
 :cpp:type:`pw::Function` objects either by const reference (``const
@@ -157,29 +158,30 @@
 
 .. code-block:: c++
 
-  // This function calls a pw::Function but doesn't store it, so it takes a
-  // const reference.
-  void CallTheCallback(const pw::Function<void(int)>& callback) {
-    callback(123);
-  }
+   // This function calls a pw::Function but doesn't store it, so it takes a
+   // const reference.
+   void CallTheCallback(const pw::Function<void(int)>& callback) {
+     callback(123);
+   }
 
-  // This function move-assigns a pw::Function to another variable, so it takes
-  // an rvalue reference.
-  void StoreTheCallback(pw::Function<void(int)>&& callback) {
-    stored_callback_ = std::move(callback);
-  }
+   // This function move-assigns a pw::Function to another variable, so it takes
+   // an rvalue reference.
+   void StoreTheCallback(pw::Function<void(int)>&& callback) {
+     stored_callback_ = std::move(callback);
+   }
 
 .. admonition:: Rules of thumb for passing a :cpp:type:`pw::Function` to a function
 
    * **Pass by value**: Never.
-
      This results in unnecessary :cpp:type:`pw::Function` instances and move
      operations.
+
    * **Pass by const reference** (``const pw::Function&``): When the
      :cpp:type:`pw::Function` is only invoked.
 
      When a :cpp:type:`pw::Function` is called or inspected, but not moved, take
      a const reference to avoid copies and support temporaries.
+
    * **Pass by rvalue reference** (``pw::Function&&``): When the
      :cpp:type:`pw::Function` is moved.
 
@@ -190,6 +192,7 @@
      :cpp:type:`pw::Function` variable, which makes the transfer of ownership
      explicit. It is possible to move-assign from an lvalue reference, but this
      fails to make it obvious to the caller that the object is no longer valid.
+
    * **Pass by non-const reference** (``pw::Function&``): Rarely, when modifying
      a variable.
 
@@ -206,11 +209,11 @@
 
 .. code-block:: c++
 
-  // Implicitly creates a pw::Function from a capturing lambda and calls it.
-  CallTheCallback([this](int result) { result_ = result; });
+   // Implicitly creates a pw::Function from a capturing lambda and calls it.
+   CallTheCallback([this](int result) { result_ = result; });
 
-  // Implicitly creates a pw::Function from a capturing lambda and stores it.
-  StoreTheCallback([this](int result) { result_ = result; });
+   // Implicitly creates a pw::Function from a capturing lambda and stores it.
+   StoreTheCallback([this](int result) { result_ = result; });
 
 When working with an existing :cpp:type:`pw::Function` variable, the variable
 can be passed directly to functions that take a const reference. If the function
@@ -219,11 +222,11 @@
 
 .. code-block:: c++
 
-  // Accepts the pw::Function by const reference.
-  CallTheCallback(my_function_);
+   // Accepts the pw::Function by const reference.
+   CallTheCallback(my_function_);
 
-  // Takes ownership of the pw::Function.
-  void StoreTheCallback(std::move(my_function));
+   // Takes ownership of the pw::Function.
+   void StoreTheCallback(std::move(my_function));
 
 ``pw::Callback`` for one-shot functions
 =======================================
@@ -247,7 +250,7 @@
 ScopeGuard
 ----------
 .. doxygenclass:: pw::ScopeGuard
-    :members:
+   :members:
 
 ------------
 Size reports
diff --git a/pw_hdlc/design.rst b/pw_hdlc/design.rst
index 06e970d..d20d774 100644
--- a/pw_hdlc/design.rst
+++ b/pw_hdlc/design.rst
@@ -22,16 +22,16 @@
 
 .. code-block:: text
 
-    _________________________________________
-    | | | |                          |    | |...
-    | | | |                          |    | |... [More frames]
-    |_|_|_|__________________________|____|_|...
-     F A C       Payload              FCS  F
+   _________________________________________
+   | | | |                          |    | |...
+   | | | |                          |    | |... [More frames]
+   |_|_|_|__________________________|____|_|...
+    F A C       Payload              FCS  F
 
-     F = flag byte (0x7e, the ~ character)
-     A = address field
-     C = control field
-     FCS = frame check sequence (CRC-32)
+    F = flag byte (0x7e, the ~ character)
+    A = address field
+    C = control field
+    FCS = frame check sequence (CRC-32)
 
 
 Encoding and sending data
@@ -40,13 +40,13 @@
 beginning of the frame. Before sending any of the payload data through serial,
 the special bytes are escaped:
 
-            +-------------------------+-----------------------+
-            | Unescaped Special Bytes | Escaped Special Bytes |
-            +=========================+=======================+
-            |           7E            |        7D 5E          |
-            +-------------------------+-----------------------+
-            |           7D            |        7D 5D          |
-            +-------------------------+-----------------------+
++-------------------------+-----------------------+
+| Unescaped Special Bytes | Escaped Special Bytes |
++=========================+=======================+
+|           7E            |        7D 5E          |
++-------------------------+-----------------------+
+|           7D            |        7D 5D          |
++-------------------------+-----------------------+
 
 The bytes of the payload are escaped and written in a single pass. The
 frame check sequence is calculated, escaped, and written after. After this, a
diff --git a/pw_i2c/docs.rst b/pw_i2c/docs.rst
index 20da554..0080fba 100644
--- a/pw_i2c/docs.rst
+++ b/pw_i2c/docs.rst
@@ -3,10 +3,9 @@
 ------
 pw_i2c
 ------
-
 .. warning::
-  This module is under construction, not ready for use, and the documentation
-  is incomplete.
+   This module is under construction, not ready for use, and the documentation
+   is incomplete.
 
 pw_i2c contains interfaces and utility functions for using I2C.
 
@@ -15,13 +14,9 @@
 
 pw::i2c::Initiator
 ------------------
-.. inclusive-language: disable
-
 .. doxygenclass:: pw::i2c::Initiator
    :members:
 
-.. inclusive-language: enable
-
 pw::i2c::Device
 ---------------
 The common interface for interfacing with generic I2C devices. This object
@@ -30,7 +25,6 @@
 with devices with a single device address.
 
 .. note::
-
    ``Device`` is intended to represent ownership of a specific responder.
    Individual transactions are atomic (as described under ``Initiator``), but
    there is no synchronization for sequences of transactions. Therefore, shared
diff --git a/pw_i2c_mcuxpresso/docs.rst b/pw_i2c_mcuxpresso/docs.rst
index 1247cd3..2211258 100644
--- a/pw_i2c_mcuxpresso/docs.rst
+++ b/pw_i2c_mcuxpresso/docs.rst
@@ -14,15 +14,15 @@
 =====
 This module requires following setup:
 
- 1. Use ``pw_build_mcuxpresso`` to create a ``pw_source_set`` for an
-    MCUXpresso SDK.
- 2. Include the i2c driver component in this SDK definition.
- 3. Specify the ``pw_third_party_mcuxpresso_SDK`` GN global variable to specify
-    the name of this source set.
- 4. Use ``pw::i2c::McuxpressoInitiator`` implementation of
-    ``pw::i2c::Initiator`` while creating ``pw::i2c::Device`` or
-    ``pw::i2c::RegisterDevice`` interface to access the I2C devices connected to
-    target.
+1. Use ``pw_build_mcuxpresso`` to create a ``pw_source_set`` for an
+   MCUXpresso SDK.
+2. Include the i2c driver component in this SDK definition.
+3. Specify the ``pw_third_party_mcuxpresso_SDK`` GN global variable to specify
+   the name of this source set.
+4. Use ``pw::i2c::McuxpressoInitiator`` implementation of
+   ``pw::i2c::Initiator`` while creating ``pw::i2c::Device`` or
+   ``pw::i2c::RegisterDevice`` interface to access the I2C devices connected to
+   target.
 
 Usage
 =====
diff --git a/pw_log/docs.rst b/pw_log/docs.rst
index d59f011..d26e238 100644
--- a/pw_log/docs.rst
+++ b/pw_log/docs.rst
@@ -17,9 +17,9 @@
 :ref:`module-pw_log-protobuf` for details.
 
 .. toctree::
-  :hidden:
+   :hidden:
 
-  protobuf
+   protobuf
 
 --------------
 Usage examples
@@ -29,19 +29,19 @@
 
 .. code-block:: cpp
 
-  #define PW_LOG_MODULE_NAME "BLE"
+   #define PW_LOG_MODULE_NAME "BLE"
 
-  #include "pw_log/log.h"
+   #include "pw_log/log.h"
 
-  int main() {
-    PW_LOG_INFO("Booting...");
-    PW_LOG_DEBUG("CPU temp: %.2f", cpu_temperature);
-    if (BootFailed()) {
-      PW_LOG_CRITICAL("Had trouble booting due to error %d", GetErrorCode());
-      ReportErrorsAndHalt();
-    }
-    PW_LOG_INFO("Successfully booted");
-  }
+   int main() {
+     PW_LOG_INFO("Booting...");
+     PW_LOG_DEBUG("CPU temp: %.2f", cpu_temperature);
+     if (BootFailed()) {
+       PW_LOG_CRITICAL("Had trouble booting due to error %d", GetErrorCode());
+       ReportErrorsAndHalt();
+     }
+     PW_LOG_INFO("Successfully booted");
+   }
 
 In ``.cc`` files, it is possible to dispense with the ``PW_`` part of the log
 names and go for shorter log macros. Include ``pw_log/short.h`` or
@@ -49,19 +49,19 @@
 
 .. code-block:: cpp
 
-  #define PW_LOG_MODULE_NAME "BLE"
+   #define PW_LOG_MODULE_NAME "BLE"
 
-  #include "pw_log/shorter.h"
+   #include "pw_log/shorter.h"
 
-  int main() {
-    INF("Booting...");
-    DBG("CPU temp: %.2f", cpu_temperature);
-    if (BootFailed()) {
-      CRT("Had trouble booting due to error %d", GetErrorCode());
-      ReportErrorsAndHalt();
-    }
-    INF("Successfully booted");
-  }
+   int main() {
+     INF("Booting...");
+     DBG("CPU temp: %.2f", cpu_temperature);
+     if (BootFailed()) {
+       CRT("Had trouble booting due to error %d", GetErrorCode());
+       ReportErrorsAndHalt();
+     }
+     INF("Successfully booted");
+   }
 
 Layer diagram example: ``stm32f429i-disc1``
 ===========================================
@@ -80,45 +80,45 @@
 
 .. c:macro:: PW_LOG(level, module, flags, fmt, ...)
 
-  This is the primary mechanism for logging.
+   This is the primary mechanism for logging.
 
-  *level* - An integer level as defined by ``pw_log/levels.h``.
+   *level* - An integer level as defined by ``pw_log/levels.h``.
 
-  *module* - A string literal for the module name. Defaults to
-  :c:macro:`PW_LOG_MODULE_NAME`.
+   *module* - A string literal for the module name. Defaults to
+   :c:macro:`PW_LOG_MODULE_NAME`.
 
-  *flags* - Arbitrary flags the backend can leverage. The semantics of these
-  flags are not defined in the facade, but are instead meant as a general
-  mechanism for communication bits of information to the logging backend.
-  ``pw_log`` reserves 2 flag bits by default, but log backends may provide for
-  more or fewer flag bits.
+   *flags* - Arbitrary flags the backend can leverage. The semantics of these
+   flags are not defined in the facade, but are instead meant as a general
+   mechanism for communication bits of information to the logging backend.
+   ``pw_log`` reserves 2 flag bits by default, but log backends may provide for
+   more or fewer flag bits.
 
-  Here are some ideas for what a backend might use flags for:
+   Here are some ideas for what a backend might use flags for:
 
-  - Example: ``HAS_PII`` - A log has personally-identifying data
-  - Example: ``HAS_DII`` - A log has device-identifying data
-  - Example: ``RELIABLE_DELIVERY`` - Ask the backend to ensure the log is
-    delivered; this may entail blocking other logs.
-  - Example: ``BEST_EFFORT`` - Don't deliver this log if it would mean blocking
-    or dropping important-flagged logs
+   - Example: ``HAS_PII`` - A log has personally-identifying data
+   - Example: ``HAS_DII`` - A log has device-identifying data
+   - Example: ``RELIABLE_DELIVERY`` - Ask the backend to ensure the log is
+     delivered; this may entail blocking other logs.
+   - Example: ``BEST_EFFORT`` - Don't deliver this log if it would mean blocking
+     or dropping important-flagged logs
 
-  *fmt* - The message to log, which may contain format specifiers like ``%d``
-  or ``%0.2f``.
+   *fmt* - The message to log, which may contain format specifiers like ``%d``
+   or ``%0.2f``.
 
-  Example:
+   Example:
 
-  .. code-block:: cpp
+   .. code-block:: cpp
 
-    PW_LOG(PW_LOG_LEVEL_INFO, PW_LOG_MODULE_NAME, PW_LOG_FLAGS, "Temp is %d degrees", temp);
-    PW_LOG(PW_LOG_LEVEL_ERROR, PW_LOG_MODULE_NAME, UNRELIABLE_DELIVERY, "It didn't work!");
+      PW_LOG(PW_LOG_LEVEL_INFO, PW_LOG_MODULE_NAME, PW_LOG_FLAGS, "Temp is %d degrees", temp);
+      PW_LOG(PW_LOG_LEVEL_ERROR, PW_LOG_MODULE_NAME, UNRELIABLE_DELIVERY, "It didn't work!");
 
-  .. note::
+   .. note::
 
-    ``PW_LOG()`` should not be used frequently; typically only when adding
-    flags to a particular message to mark PII or to indicate delivery
-    guarantees.  For most cases, prefer to use the direct ``PW_LOG_INFO`` or
-    ``PW_LOG_DEBUG`` style macros, which are often implemented more efficiently
-    in the backend.
+      ``PW_LOG()`` should not be used frequently; typically only when adding
+      flags to a particular message to mark PII or to indicate delivery
+      guarantees.  For most cases, prefer to use the direct ``PW_LOG_INFO`` or
+      ``PW_LOG_DEBUG`` style macros, which are often implemented more efficiently
+      in the backend.
 
 
 .. c:macro:: PW_LOG_DEBUG(fmt, ...)
@@ -127,7 +127,7 @@
 .. c:macro:: PW_LOG_ERROR(fmt, ...)
 .. c:macro:: PW_LOG_CRITICAL(fmt, ...)
 
-  Shorthand for ``PW_LOG(<level>, PW_LOG_MODULE_NAME, PW_LOG_FLAGS, fmt, ...)``.
+   Shorthand for ``PW_LOG(<level>, PW_LOG_MODULE_NAME, PW_LOG_FLAGS, fmt, ...)``.
 
 --------------------
 Module configuration
@@ -139,22 +139,22 @@
 
 .. c:macro:: PW_LOG_LEVEL_DEFAULT
 
-  Controls the default value of ``PW_LOG_LEVEL``. Setting
-  ``PW_LOG_LEVEL_DEFAULT`` will change the behavior of all source files that
-  have not explicitly set ``PW_LOG_LEVEL``. Defaults to ``PW_LOG_LEVEL_DEBUG``.
+   Controls the default value of ``PW_LOG_LEVEL``. Setting
+   ``PW_LOG_LEVEL_DEFAULT`` will change the behavior of all source files that
+   have not explicitly set ``PW_LOG_LEVEL``. Defaults to ``PW_LOG_LEVEL_DEBUG``.
 
 .. c:macro:: PW_LOG_FLAGS_DEFAULT
 
-  Controls the default value of ``PW_LOG_FLAGS``. Setting
-  ``PW_LOG_FLAGS_DEFAULT`` will change the behavior of all source files that
-  have not explicitly set ``PW_LOG_FLAGS``. Defaults to ``0``.
+   Controls the default value of ``PW_LOG_FLAGS``. Setting
+   ``PW_LOG_FLAGS_DEFAULT`` will change the behavior of all source files that
+   have not explicitly set ``PW_LOG_FLAGS``. Defaults to ``0``.
 
 .. c:macro:: PW_LOG_ENABLE_IF_DEFAULT
 
-  Controls the default value of ``PW_LOG_ENABLE_IF``. Setting
-  ``PW_LOG_ENABLE_IF_DEFAULT`` will change the behavior of all source files that
-  have not explicitly set ``PW_LOG_ENABLE_IF``. Defaults to
-  ``((level) >= PW_LOG_LEVEL)``.
+   Controls the default value of ``PW_LOG_ENABLE_IF``. Setting
+   ``PW_LOG_ENABLE_IF_DEFAULT`` will change the behavior of all source files that
+   have not explicitly set ``PW_LOG_ENABLE_IF``. Defaults to
+   ``((level) >= PW_LOG_LEVEL)``.
 
 
 Per-source file configuration
@@ -168,38 +168,38 @@
 ``#defines`` before all ``#include`` statements. This should only be done in
 source files, not headers. For example:
 
-  .. code-block:: cpp
+.. code-block:: cpp
 
-    // Set the pw_log option macros here, before ALL of the #includes.
-    #define PW_LOG_MODULE_NAME "Calibration"
-    #define PW_LOG_LEVEL PW_LOG_LEVEL_WARN
+   // Set the pw_log option macros here, before ALL of the #includes.
+   #define PW_LOG_MODULE_NAME "Calibration"
+   #define PW_LOG_LEVEL PW_LOG_LEVEL_WARN
 
-    #include <array>
-    #include <random>
+   #include <array>
+   #include <random>
 
-    #include "devices/hal9000.h"
-    #include "pw_log/log.h"
-    #include "pw_rpc/server.h"
+   #include "devices/hal9000.h"
+   #include "pw_log/log.h"
+   #include "pw_rpc/server.h"
 
-    int MyFunction() {
-      PW_LOG_INFO("hello???");
-    }
+   int MyFunction() {
+     PW_LOG_INFO("hello???");
+   }
 
 .. c:macro:: PW_LOG_MODULE_NAME
 
-  A string literal module name to use in logs. Log backends may attach this
-  name to log messages or use it for runtime filtering. Defaults to ``""``. The
-  ``PW_LOG_MODULE_NAME_DEFINED`` macro is set to ``1`` or ``0`` to indicate
-  whether ``PW_LOG_MODULE_NAME`` was overridden.
+   A string literal module name to use in logs. Log backends may attach this
+   name to log messages or use it for runtime filtering. Defaults to ``""``. The
+   ``PW_LOG_MODULE_NAME_DEFINED`` macro is set to ``1`` or ``0`` to indicate
+   whether ``PW_LOG_MODULE_NAME`` was overridden.
 
 .. c:macro:: PW_LOG_FLAGS
 
-  Log flags to use for the ``PW_LOG_<level>`` macros. Different flags may be
-  applied when using the ``PW_LOG`` macro directly.
+   Log flags to use for the ``PW_LOG_<level>`` macros. Different flags may be
+   applied when using the ``PW_LOG`` macro directly.
 
-  Log backends use flags to change how they handle individual log messages.
-  Potential uses include assigning logs priority or marking them as containing
-  personal information. Defaults to ``PW_LOG_FLAGS_DEFAULT``.
+   Log backends use flags to change how they handle individual log messages.
+   Potential uses include assigning logs priority or marking them as containing
+   personal information. Defaults to ``PW_LOG_FLAGS_DEFAULT``.
 
 .. c:macro:: PW_LOG_LEVEL
 
@@ -211,15 +211,15 @@
 
    .. code-block:: cpp
 
-     #define PW_LOG_LEVEL PW_LOG_LEVEL_INFO
+      #define PW_LOG_LEVEL PW_LOG_LEVEL_INFO
 
-     #include "pw_log/log.h"
+      #include "pw_log/log.h"
 
-     void DoSomething() {
-       PW_LOG_DEBUG("This won't be logged at all");
-       PW_LOG_INFO("This is INFO level, and will display");
-       PW_LOG_WARN("This is above INFO level, and will display");
-     }
+      void DoSomething() {
+        PW_LOG_DEBUG("This won't be logged at all");
+        PW_LOG_INFO("This is INFO level, and will display");
+        PW_LOG_WARN("This is above INFO level, and will display");
+      }
 
 .. c:macro:: PW_LOG_ENABLE_IF(level, flags)
 
@@ -232,37 +232,37 @@
 
    .. code-block:: cpp
 
-     // Pigweed's log facade will call this macro to decide to log or not. In
-     // this case, it will drop logs with the PII flag set if display of PII is
-     // not enabled for the application.
-     #define PW_LOG_ENABLE_IF(level, flags) \
-         (level >= PW_LOG_LEVEL_INFO && \
-          !((flags & MY_PRODUCT_PII_MASK) && MY_PRODUCT_LOG_PII_ENABLED)
+      // Pigweed's log facade will call this macro to decide to log or not. In
+      // this case, it will drop logs with the PII flag set if display of PII is
+      // not enabled for the application.
+      #define PW_LOG_ENABLE_IF(level, flags) \
+          (level >= PW_LOG_LEVEL_INFO && \
+           !((flags & MY_PRODUCT_PII_MASK) && MY_PRODUCT_LOG_PII_ENABLED)
 
-     #include "pw_log/log.h"
+      #include "pw_log/log.h"
 
-     // This define might be supplied by the build system.
-     #define MY_PRODUCT_LOG_PII_ENABLED false
+      // This define might be supplied by the build system.
+      #define MY_PRODUCT_LOG_PII_ENABLED false
 
-     // This is the PII mask bit selected by the application.
-     #define MY_PRODUCT_PII_MASK (1 << 5)
+      // This is the PII mask bit selected by the application.
+      #define MY_PRODUCT_PII_MASK (1 << 5)
 
-     void DoSomethingWithSensitiveInfo() {
-       PW_LOG_DEBUG("This won't be logged at all");
-       PW_LOG_INFO("This is INFO level, and will display");
+      void DoSomethingWithSensitiveInfo() {
+        PW_LOG_DEBUG("This won't be logged at all");
+        PW_LOG_INFO("This is INFO level, and will display");
 
-       // In this example, this will not be logged since logging with PII
-       // is disabled by the above macros.
-       PW_LOG(PW_LOG_LEVEL_INFO,
-              MY_PRODUCT_PII_MASK,
-              "Sensitive: %d",
-              sensitive_info);
-     }
+        // In this example, this will not be logged since logging with PII
+        // is disabled by the above macros.
+        PW_LOG(PW_LOG_LEVEL_INFO,
+               MY_PRODUCT_PII_MASK,
+               "Sensitive: %d",
+               sensitive_info);
+      }
 
 .. attention::
 
-  At this time, only compile time filtering is supported. In the future, we
-  plan to add support for runtime filtering.
+   At this time, only compile time filtering is supported. In the future, we
+   plan to add support for runtime filtering.
 
 ------------------
 Logging attributes
@@ -329,15 +329,15 @@
 
 .. c:macro:: PW_LOG_CFG_GLOG_BUFFER_SIZE_BYTES
 
-  The size of the stack-allocated buffer used by the Google Logging (glog)
-  macros. This only affects the glog macros provided through pw_log/glog.h.
+   The size of the stack-allocated buffer used by the Google Logging (glog)
+   macros. This only affects the glog macros provided through pw_log/glog.h.
 
-  Pigweed strongly recommends sticking to printf-style logging instead
-  of C++ stream-style Google Log logging unless absolutely necessary. The glog
-  macros are only provided for compatibility with non-embedded code. See
-  :ref:`module-pw_log-design-discussion` for more details.
+   Pigweed strongly recommends sticking to printf-style logging instead
+   of C++ stream-style Google Log logging unless absolutely necessary. The glog
+   macros are only provided for compatibility with non-embedded code. See
+   :ref:`module-pw_log-design-discussion` for more details.
 
-  Undersizing this buffer will result in truncated log messages.
+   Undersizing this buffer will result in truncated log messages.
 
 -----------------
 Design discussion
@@ -356,14 +356,14 @@
 
 .. code-block:: cpp
 
-  LOG(INFO) << "My temperature is " << temperature << ". State: " << state;
+   LOG(INFO) << "My temperature is " << temperature << ". State: " << state;
 
 This log statement has two string literals. It might seem like one could convert
 move to tokenization:
 
 .. code-block:: cpp
 
-  LOG(INFO) << TOKEN("My temperature is ") << temperature << TOKEN(". State: ") << state;
+   LOG(INFO) << TOKEN("My temperature is ") << temperature << TOKEN(". State: ") << state;
 
 However, this doesn't work. The key problem is that the tokenization system
 needs to allocate the string in a linker section that is excluded from the
@@ -378,8 +378,8 @@
 
 .. code-block:: cpp
 
-  // Note: LOG_INFO can be tokenized behind the macro; transparent to users.
-  PW_LOG_INFO("My temperature is %d. State: %s", temperature, state);
+   // Note: LOG_INFO can be tokenized behind the macro; transparent to users.
+   PW_LOG_INFO("My temperature is %d. State: %s", temperature, state);
 
 Additionally, while Pigweed is mostly C++, it a practical reality that at times
 projects using Pigweed will need to log from third-party libraries written in
diff --git a/pw_malloc/docs.rst b/pw_malloc/docs.rst
index 2c0357d..53249f5 100644
--- a/pw_malloc/docs.rst
+++ b/pw_malloc/docs.rst
@@ -3,7 +3,6 @@
 ---------
 pw_malloc
 ---------
-
 This module defines an interface for replacing the standard libc dynamic memory
 operations.
 
@@ -19,9 +18,9 @@
 =====
 This module requires the following setup:
 
-  1. Chose a ``pw_malloc`` backend, or write one yourself.
-  2. If using GN build, Specify the ``pw_malloc_BACKEND`` GN build arg to point
-     the library that provides a ``pw_malloc`` backend.
+1. Chose a ``pw_malloc`` backend, or write one yourself.
+2. If using GN build, Specify the ``pw_malloc_BACKEND`` GN build arg to point
+   the library that provides a ``pw_malloc`` backend.
 
 Module usage
 ============
diff --git a/pw_metric/docs.rst b/pw_metric/docs.rst
index 9386365..080a3ad 100644
--- a/pw_metric/docs.rst
+++ b/pw_metric/docs.rst
@@ -5,9 +5,8 @@
 =========
 
 .. attention::
-
-  This module is **not yet production ready**; ask us if you are interested in
-  using it out or have ideas about how to improve it.
+   This module is **not yet production ready**; ask us if you are interested in
+   using it out or have ideas about how to improve it.
 
 --------
 Overview
@@ -180,20 +179,20 @@
 
 .. cpp:class:: pw::metric::Metric
 
-  .. cpp:function:: Increment(uint32_t amount = 0)
+   .. cpp:function:: Increment(uint32_t amount = 0)
 
-    Increment the metric by the given amount. Results in undefined behaviour if
-    the metric is not of type int.
+      Increment the metric by the given amount. Results in undefined behaviour if
+      the metric is not of type int.
 
-  .. cpp:function:: Set(uint32_t value)
+   .. cpp:function:: Set(uint32_t value)
 
-    Set the metric to the given value. Results in undefined behaviour if the
-    metric is not of type int.
+      Set the metric to the given value. Results in undefined behaviour if the
+      metric is not of type int.
 
-  .. cpp:function:: Set(float value)
+   .. cpp:function:: Set(float value)
 
-    Set the metric to the given value. Results in undefined behaviour if the
-    metric is not of type float.
+      Set the metric to the given value. Results in undefined behaviour if the
+      metric is not of type float.
 
 Group
 -----
@@ -208,39 +207,39 @@
 
 .. cpp:class:: pw::metric::Group
 
-  .. cpp:function:: Dump(int indent_level = 0)
+   .. cpp:function:: Dump(int indent_level = 0)
 
-    Recursively dump a metrics group to ``pw_log``. Produces output like:
+      Recursively dump a metrics group to ``pw_log``. Produces output like:
 
-    .. code:: none
+      .. code:: none
 
-      "$6doqFw==": {
-        "$05OCZw==": {
-          "$VpPfzg==": 1,
-          "$LGPMBQ==": 1.000000,
-          "$+iJvUg==": 5,
-        }
-        "$9hPNxw==": 65,
-        "$oK7HmA==": 13,
-        "$FCM4qQ==": 0,
-      }
+         "$6doqFw==": {
+           "$05OCZw==": {
+             "$VpPfzg==": 1,
+             "$LGPMBQ==": 1.000000,
+             "$+iJvUg==": 5,
+           }
+           "$9hPNxw==": 65,
+           "$oK7HmA==": 13,
+           "$FCM4qQ==": 0,
+         }
 
-    Note the metric names are tokenized with base64. Decoding requires using
-    the Pigweed detokenizer. With a detokenizing-enabled logger, you could get
-    something like:
+      Note the metric names are tokenized with base64. Decoding requires using
+      the Pigweed detokenizer. With a detokenizing-enabled logger, you could get
+      something like:
 
-    .. code:: none
+      .. code:: none
 
-      "i2c_1": {
-        "gyro": {
-          "num_sampleses": 1,
-          "init_time_us": 1.000000,
-          "initialized": 5,
-        }
-        "bus_errors": 65,
-        "transactions": 13,
-        "bytes_sent": 0,
-      }
+         "i2c_1": {
+           "gyro": {
+             "num_sampleses": 1,
+             "init_time_us": 1.000000,
+             "initialized": 5,
+           }
+           "bus_errors": 65,
+           "transactions": 13,
+           "bytes_sent": 0,
+         }
 
 Macros
 ------
@@ -253,150 +252,147 @@
 .. cpp:function:: PW_METRIC_STATIC(identifier, name, value)
 .. cpp:function:: PW_METRIC_STATIC(group, identifier, name, value)
 
-  Declare a metric, optionally adding it to a group.
+   Declare a metric, optionally adding it to a group.
 
-  - **identifier** - An identifier name for the created variable or member.
-    For example: ``i2c_transactions`` might be used as a local or global
-    metric; inside a class, could be named according to members
-    (``i2c_transactions_`` for Google's C++ style).
-  - **name** - The string name for the metric. This will be tokenized. There
-    are no restrictions on the contents of the name; however, consider
-    restricting these to be valid C++ identifiers to ease integration with
-    other systems.
-  - **value** - The initial value for the metric. Must be either a floating
-    point value (e.g. ``3.2f``) or unsigned int (e.g. ``21u``).
-  - **group** - A ``pw::metric::Group`` instance. If provided, the metric is
-    added to the given group.
+   - **identifier** - An identifier name for the created variable or member.
+     For example: ``i2c_transactions`` might be used as a local or global
+     metric; inside a class, could be named according to members
+     (``i2c_transactions_`` for Google's C++ style).
+   - **name** - The string name for the metric. This will be tokenized. There
+     are no restrictions on the contents of the name; however, consider
+     restricting these to be valid C++ identifiers to ease integration with
+     other systems.
+   - **value** - The initial value for the metric. Must be either a floating
+     point value (e.g. ``3.2f``) or unsigned int (e.g. ``21u``).
+   - **group** - A ``pw::metric::Group`` instance. If provided, the metric is
+     added to the given group.
 
-  The macro declares a variable or member named "name" with type
-  ``pw::metric::Metric``, and works in three contexts: global, local, and
-  member.
+   The macro declares a variable or member named "name" with type
+   ``pw::metric::Metric``, and works in three contexts: global, local, and
+   member.
 
-  If the `_STATIC` variant is used, the macro declares a variable with static
-  storage. These can be used in function scopes, but not in classes.
+   If the `_STATIC` variant is used, the macro declares a variable with static
+   storage. These can be used in function scopes, but not in classes.
 
-  1. At global scope:
+   1. At global scope:
 
-    .. code::
+      .. code::
 
-      PW_METRIC(foo, "foo", 15.5f);
+         PW_METRIC(foo, "foo", 15.5f);
 
-      void MyFunc() {
-        foo.Increment();
-      }
+         void MyFunc() {
+           foo.Increment();
+         }
 
-  2. At local function or member function scope:
+   2. At local function or member function scope:
 
-    .. code::
+      .. code::
 
-      void MyFunc() {
-        PW_METRIC(foo, "foo", 15.5f);
-        foo.Increment();
-        // foo goes out of scope here; be careful!
-      }
+         void MyFunc() {
+           PW_METRIC(foo, "foo", 15.5f);
+           foo.Increment();
+           // foo goes out of scope here; be careful!
+         }
 
-  3. At member level inside a class or struct:
+   3. At member level inside a class or struct:
 
-    .. code::
+      .. code::
 
-      struct MyStructy {
-        void DoSomething() {
-          somethings.Increment();
-        }
-        // Every instance of MyStructy will have a separate somethings counter.
-        PW_METRIC(somethings, "somethings", 0u);
-      }
+         struct MyStructy {
+           void DoSomething() {
+             somethings.Increment();
+           }
+           // Every instance of MyStructy will have a separate somethings counter.
+           PW_METRIC(somethings, "somethings", 0u);
+         }
 
-  You can also put a metric into a group with the macro. Metrics can belong to
-  strictly one group, otherwise an assertion will fail. Example:
+   You can also put a metric into a group with the macro. Metrics can belong to
+   strictly one group, otherwise an assertion will fail. Example:
 
-  .. code::
+   .. code::
 
-    PW_METRIC_GROUP(my_group, "my_group");
-    PW_METRIC(my_group, foo, "foo", 0.2f);
-    PW_METRIC(my_group, bar, "bar", 44000u);
-    PW_METRIC(my_group, zap, "zap", 3.14f);
+      PW_METRIC_GROUP(my_group, "my_group");
+      PW_METRIC(my_group, foo, "foo", 0.2f);
+      PW_METRIC(my_group, bar, "bar", 44000u);
+      PW_METRIC(my_group, zap, "zap", 3.14f);
 
-  .. tip::
-
-    If you want a globally registered metric, see ``pw_metric/global.h``; in
-    that contexts, metrics are globally registered without the need to
-    centrally register in a single place.
+   .. tip::
+      If you want a globally registered metric, see ``pw_metric/global.h``; in
+      that contexts, metrics are globally registered without the need to
+      centrally register in a single place.
 
 .. cpp:function:: PW_METRIC_GROUP(identifier, name)
 .. cpp:function:: PW_METRIC_GROUP(parent_group, identifier, name)
 .. cpp:function:: PW_METRIC_GROUP_STATIC(identifier, name)
 .. cpp:function:: PW_METRIC_GROUP_STATIC(parent_group, identifier, name)
 
-  Declares a ``pw::metric::Group`` with name name; the name is tokenized.
-  Works similar to ``PW_METRIC`` and can be used in the same contexts (global,
-  local, and member). Optionally, the group can be added to a parent group.
+   Declares a ``pw::metric::Group`` with name name; the name is tokenized.
+   Works similar to ``PW_METRIC`` and can be used in the same contexts (global,
+   local, and member). Optionally, the group can be added to a parent group.
 
-  If the `_STATIC` variant is used, the macro declares a variable with static
-  storage. These can be used in function scopes, but not in classes.
+   If the `_STATIC` variant is used, the macro declares a variable with static
+   storage. These can be used in function scopes, but not in classes.
 
-  Example:
+   Example:
 
-  .. code::
+   .. code::
 
-    PW_METRIC_GROUP(my_group, "my_group");
-    PW_METRIC(my_group, foo, "foo", 0.2f);
-    PW_METRIC(my_group, bar, "bar", 44000u);
-    PW_METRIC(my_group, zap, "zap", 3.14f);
+      PW_METRIC_GROUP(my_group, "my_group");
+      PW_METRIC(my_group, foo, "foo", 0.2f);
+      PW_METRIC(my_group, bar, "bar", 44000u);
+      PW_METRIC(my_group, zap, "zap", 3.14f);
 
 .. cpp:function:: PW_METRIC_GLOBAL(identifier, name, value)
 
-  Declare a ``pw::metric::Metric`` with name name, and register it in the
-  global metrics list ``pw::metric::global_metrics``.
+   Declare a ``pw::metric::Metric`` with name name, and register it in the
+   global metrics list ``pw::metric::global_metrics``.
 
-  Example:
+   Example:
 
-  .. code::
+   .. code::
 
-    #include "pw_metric/metric.h"
-    #include "pw_metric/global.h"
+      #include "pw_metric/metric.h"
+      #include "pw_metric/global.h"
 
-    // No need to coordinate collection of foo and bar; they're autoregistered.
-    PW_METRIC_GLOBAL(foo, "foo", 0.2f);
-    PW_METRIC_GLOBAL(bar, "bar", 44000u);
+      // No need to coordinate collection of foo and bar; they're autoregistered.
+      PW_METRIC_GLOBAL(foo, "foo", 0.2f);
+      PW_METRIC_GLOBAL(bar, "bar", 44000u);
 
-  Note that metrics defined with ``PW_METRIC_GLOBAL`` should never be added to
-  groups defined with ``PW_METRIC_GROUP_GLOBAL``. Each metric can only belong
-  to one group, and metrics defined with ``PW_METRIC_GLOBAL`` are
-  pre-registered with the global metrics list.
+   Note that metrics defined with ``PW_METRIC_GLOBAL`` should never be added to
+   groups defined with ``PW_METRIC_GROUP_GLOBAL``. Each metric can only belong
+   to one group, and metrics defined with ``PW_METRIC_GLOBAL`` are
+   pre-registered with the global metrics list.
 
-  .. attention::
-
-    Do not create ``PW_METRIC_GLOBAL`` instances anywhere other than global
-    scope. Putting these on an instance (member context) would lead to dangling
-    pointers and misery. Metrics are never deleted or unregistered!
+   .. attention::
+      Do not create ``PW_METRIC_GLOBAL`` instances anywhere other than global
+      scope. Putting these on an instance (member context) would lead to dangling
+      pointers and misery. Metrics are never deleted or unregistered!
 
 .. cpp:function:: PW_METRIC_GROUP_GLOBAL(identifier, name, value)
 
-  Declare a ``pw::metric::Group`` with name name, and register it in the
-  global metric groups list ``pw::metric::global_groups``.
+   Declare a ``pw::metric::Group`` with name name, and register it in the
+   global metric groups list ``pw::metric::global_groups``.
 
-  Note that metrics created with ``PW_METRIC_GLOBAL`` should never be added to
-  groups! Instead, just create a freestanding metric and register it into the
-  global group (like in the example below).
+   Note that metrics created with ``PW_METRIC_GLOBAL`` should never be added to
+   groups! Instead, just create a freestanding metric and register it into the
+   global group (like in the example below).
 
-  Example:
+   Example:
 
-  .. code::
+   .. code::
 
-    #include "pw_metric/metric.h"
-    #include "pw_metric/global.h"
+      #include "pw_metric/metric.h"
+      #include "pw_metric/global.h"
 
-    // No need to coordinate collection of this group; it's globally registered.
-    PW_METRIC_GROUP_GLOBAL(leagcy_system, "legacy_system");
-    PW_METRIC(leagcy_system, foo, "foo",0.2f);
-    PW_METRIC(leagcy_system, bar, "bar",44000u);
+      // No need to coordinate collection of this group; it's globally registered.
+      PW_METRIC_GROUP_GLOBAL(leagcy_system, "legacy_system");
+      PW_METRIC(leagcy_system, foo, "foo",0.2f);
+      PW_METRIC(leagcy_system, bar, "bar",44000u);
 
-  .. attention::
-
-    Do not create ``PW_METRIC_GROUP_GLOBAL`` instances anywhere other than
-    global scope. Putting these on an instance (member context) would lead to
-    dangling pointers and misery. Metrics are never deleted or unregistered!
+   .. attention::
+      Do not create ``PW_METRIC_GROUP_GLOBAL`` instances anywhere other than
+      global scope. Putting these on an instance (member context) would lead to
+      dangling pointers and misery. Metrics are never deleted or unregistered!
 
 ----------------------
 Usage & Best Practices
@@ -415,21 +411,21 @@
 
 .. code::
 
-  class Uart {
-   public:
-    Uart(span<std::byte> rx_buffer, span<std::byte> tx_buffer)
-      : rx_buffer_(rx_buffer), tx_buffer_(tx_buffer) {}
+   class Uart {
+    public:
+     Uart(span<std::byte> rx_buffer, span<std::byte> tx_buffer)
+       : rx_buffer_(rx_buffer), tx_buffer_(tx_buffer) {}
 
-    // Send/receive here...
+     // Send/receive here...
 
-   private:
-    pw::span<std::byte> rx_buffer;
-    pw::span<std::byte> tx_buffer;
-  };
+    private:
+     pw::span<std::byte> rx_buffer;
+     pw::span<std::byte> tx_buffer;
+   };
 
-  std::array<std::byte, 512> uart_rx_buffer;
-  std::array<std::byte, 512> uart_tx_buffer;
-  Uart uart1(uart_rx_buffer, uart_tx_buffer);
+   std::array<std::byte, 512> uart_rx_buffer;
+   std::array<std::byte, 512> uart_tx_buffer;
+   Uart uart1(uart_rx_buffer, uart_tx_buffer);
 
 Through the course of building a product, the team may want to add metrics to
 the UART to for example gain insight into which operations are triggering lots
@@ -438,37 +434,37 @@
 
 .. code::
 
-  class Uart {
-   public:
-    Uart(span<std::byte> rx_buffer,
-         span<std::byte> tx_buffer,
-         Group& parent_metrics)
-      : rx_buffer_(rx_buffer),
-        tx_buffer_(tx_buffer) {
-        // PROBLEM! parent_metrics may not be constructed if it's a reference
-        // to a static global.
-        parent_metrics.Add(tx_bytes_);
-        parent_metrics.Add(rx_bytes_);
-     }
+   class Uart {
+    public:
+     Uart(span<std::byte> rx_buffer,
+          span<std::byte> tx_buffer,
+          Group& parent_metrics)
+       : rx_buffer_(rx_buffer),
+         tx_buffer_(tx_buffer) {
+         // PROBLEM! parent_metrics may not be constructed if it's a reference
+         // to a static global.
+         parent_metrics.Add(tx_bytes_);
+         parent_metrics.Add(rx_bytes_);
+      }
 
-    // Send/receive here which increment tx/rx_bytes.
+     // Send/receive here which increment tx/rx_bytes.
 
-   private:
-    pw::span<std::byte> rx_buffer;
-    pw::span<std::byte> tx_buffer;
+    private:
+     pw::span<std::byte> rx_buffer;
+     pw::span<std::byte> tx_buffer;
 
-    PW_METRIC(tx_bytes_, "tx_bytes", 0);
-    PW_METRIC(rx_bytes_, "rx_bytes", 0);
-  };
+     PW_METRIC(tx_bytes_, "tx_bytes", 0);
+     PW_METRIC(rx_bytes_, "rx_bytes", 0);
+   };
 
-  PW_METRIC_GROUP(global_metrics, "/");
-  PW_METRIC_GROUP(global_metrics, uart1_metrics, "uart1");
+   PW_METRIC_GROUP(global_metrics, "/");
+   PW_METRIC_GROUP(global_metrics, uart1_metrics, "uart1");
 
-  std::array<std::byte, 512> uart_rx_buffer;
-  std::array<std::byte, 512> uart_tx_buffer;
-  Uart uart1(uart_rx_buffer,
-             uart_tx_buffer,
-             uart1_metrics);
+   std::array<std::byte, 512> uart_rx_buffer;
+   std::array<std::byte, 512> uart_tx_buffer;
+   Uart uart1(uart_rx_buffer,
+              uart_tx_buffer,
+              uart1_metrics);
 
 However, this **is incorrect**, since the ``parent_metrics`` (pointing to
 ``uart1_metrics`` in this case) may not be constructed at the point of
@@ -486,48 +482,47 @@
 
 .. code::
 
-  class Uart {
-   public:
-    // Note that metrics is not passed in here at all.
-    Uart(span<std::byte> rx_buffer,
-         span<std::byte> tx_buffer)
-      : rx_buffer_(rx_buffer),
-        tx_buffer_(tx_buffer) {}
+   class Uart {
+    public:
+     // Note that metrics is not passed in here at all.
+     Uart(span<std::byte> rx_buffer,
+          span<std::byte> tx_buffer)
+       : rx_buffer_(rx_buffer),
+         tx_buffer_(tx_buffer) {}
 
-     // Precondition: parent_metrics is already constructed.
-     void Init(Group& parent_metrics) {
-        parent_metrics.Add(tx_bytes_);
-        parent_metrics.Add(rx_bytes_);
-     }
+      // Precondition: parent_metrics is already constructed.
+      void Init(Group& parent_metrics) {
+         parent_metrics.Add(tx_bytes_);
+         parent_metrics.Add(rx_bytes_);
+      }
 
-    // Send/receive here which increment tx/rx_bytes.
+     // Send/receive here which increment tx/rx_bytes.
 
-   private:
-    pw::span<std::byte> rx_buffer;
-    pw::span<std::byte> tx_buffer;
+    private:
+     pw::span<std::byte> rx_buffer;
+     pw::span<std::byte> tx_buffer;
 
-    PW_METRIC(tx_bytes_, "tx_bytes", 0);
-    PW_METRIC(rx_bytes_, "rx_bytes", 0);
-  };
+     PW_METRIC(tx_bytes_, "tx_bytes", 0);
+     PW_METRIC(rx_bytes_, "rx_bytes", 0);
+   };
 
-  PW_METRIC_GROUP(root_metrics, "/");
-  PW_METRIC_GROUP(root_metrics, uart1_metrics, "uart1");
+   PW_METRIC_GROUP(root_metrics, "/");
+   PW_METRIC_GROUP(root_metrics, uart1_metrics, "uart1");
 
-  std::array<std::byte, 512> uart_rx_buffer;
-  std::array<std::byte, 512> uart_tx_buffer;
-  Uart uart1(uart_rx_buffer,
-             uart_tx_buffer);
+   std::array<std::byte, 512> uart_rx_buffer;
+   std::array<std::byte, 512> uart_tx_buffer;
+   Uart uart1(uart_rx_buffer,
+              uart_tx_buffer);
 
-  void main() {
-    // uart1_metrics is guaranteed to be initialized by this point, so it is
-    safe to pass it to Init().
-    uart1.Init(uart1_metrics);
-  }
+   void main() {
+     // uart1_metrics is guaranteed to be initialized by this point, so it is
+     safe to pass it to Init().
+     uart1.Init(uart1_metrics);
+   }
 
 .. attention::
-
-  Be extra careful about **static global metric registration**. Consider using
-  the ``Init()`` pattern.
+   Be extra careful about **static global metric registration**. Consider using
+   the ``Init()`` pattern.
 
 Metric member order matters in objects
 --------------------------------------
@@ -537,40 +532,40 @@
 
 .. code::
 
-  #include "pw_metric/metric.h"
+   #include "pw_metric/metric.h"
 
-  class PowerSubsystem {
-   public:
-     Group& metrics() { return metrics_; }
-     const Group& metrics() const { return metrics_; }
+   class PowerSubsystem {
+    public:
+      Group& metrics() { return metrics_; }
+      const Group& metrics() const { return metrics_; }
 
-   private:
-    PW_METRIC_GROUP(metrics_, "power");  // Note metrics_ declared first.
-    PW_METRIC(metrics_, foo, "foo", 0.2f);
-    PW_METRIC(metrics_, bar, "bar", 44000u);
-  };
+    private:
+     PW_METRIC_GROUP(metrics_, "power");  // Note metrics_ declared first.
+     PW_METRIC(metrics_, foo, "foo", 0.2f);
+     PW_METRIC(metrics_, bar, "bar", 44000u);
+   };
 
 but the following one will not since the group is constructed after the metrics
 (and will result in a compile error):
 
 .. code::
 
-  #include "pw_metric/metric.h"
+   #include "pw_metric/metric.h"
 
-  class PowerSubsystem {
-   public:
-     Group& metrics() { return metrics_; }
-     const Group& metrics() const { return metrics_; }
+   class PowerSubsystem {
+    public:
+      Group& metrics() { return metrics_; }
+      const Group& metrics() const { return metrics_; }
 
-   private:
-    PW_METRIC(metrics_, foo, "foo", 0.2f);
-    PW_METRIC(metrics_, bar, "bar", 44000u);
-    PW_METRIC_GROUP(metrics_, "power");  // Error: metrics_ must be first.
-  };
+    private:
+     PW_METRIC(metrics_, foo, "foo", 0.2f);
+     PW_METRIC(metrics_, bar, "bar", 44000u);
+     PW_METRIC_GROUP(metrics_, "power");  // Error: metrics_ must be first.
+   };
 
 .. attention::
 
-  Put **groups before metrics** when declaring metrics members inside classes.
+   Put **groups before metrics** when declaring metrics members inside classes.
 
 Thread safety
 -------------
@@ -586,9 +581,9 @@
 
 .. attention::
 
-  **You must synchronize access to metrics**. ``pw_metrics`` does not
-  internally synchronize access during construction. Metric Set/Increment are
-  safe.
+   **You must synchronize access to metrics**. ``pw_metrics`` does not
+   internally synchronize access during construction. Metric Set/Increment are
+   safe.
 
 Lifecycle
 ---------
@@ -609,24 +604,23 @@
 
 .. code::
 
-  #include "pw_metric/metric.h"
+   #include "pw_metric/metric.h"
 
-  void main() {
-    PW_METRIC_GROUP(root, "/");
-    {
-      // BAD! The metrics have a different lifetime than the group.
-      PW_METRIC(root, temperature, "temperature_f", 72.3f);
-      PW_METRIC(root, humidity, "humidity_relative_percent", 33.2f);
-    }
-    // OOPS! root now has a linked list that points to the destructed
-    // "humidity" object.
-  }
+   void main() {
+     PW_METRIC_GROUP(root, "/");
+     {
+       // BAD! The metrics have a different lifetime than the group.
+       PW_METRIC(root, temperature, "temperature_f", 72.3f);
+       PW_METRIC(root, humidity, "humidity_relative_percent", 33.2f);
+     }
+     // OOPS! root now has a linked list that points to the destructed
+     // "humidity" object.
+   }
 
 .. attention::
-
-  **Don't destruct metrics**. Metrics are designed to be registered /
-  structured upfront, then manipulated during a device's active phase. They do
-  not support destruction.
+   **Don't destruct metrics**. Metrics are designed to be registered /
+   structured upfront, then manipulated during a device's active phase. They do
+   not support destruction.
 
 -----------------
 Exporting metrics
@@ -648,14 +642,14 @@
 
 .. code:: none
 
-  {
-    "/i2c1/failed_txns": 17,
-    "/i2c1/total_txns": 2013,
-    "/i2c1/gyro/resets": 24,
-    "/i2c1/gyro/hangs": 1,
-    "/spi1/thermocouple/reads": 242,
-    "/spi1/thermocouple/temp_celsius": 34.52,
-  }
+   {
+     "/i2c1/failed_txns": 17,
+     "/i2c1/total_txns": 2013,
+     "/i2c1/gyro/resets": 24,
+     "/i2c1/gyro/hangs": 1,
+     "/spi1/thermocouple/reads": 242,
+     "/spi1/thermocouple/temp_celsius": 34.52,
+   }
 
 Note that there is no nesting of the groups; the nesting is implied from the
 path.
@@ -705,25 +699,23 @@
    }
 
 .. attention::
-
-  Take care when exporting metrics. Ensure **appropriate access control** is in
-  place. In some cases it may make sense to entirely disable metrics export for
-  production builds. Although reading metrics via RPC won't influence the
-  device, in some cases the metrics could expose sensitive information if
-  product owners are not careful.
+   Take care when exporting metrics. Ensure **appropriate access control** is in
+   place. In some cases it may make sense to entirely disable metrics export for
+   production builds. Although reading metrics via RPC won't influence the
+   device, in some cases the metrics could expose sensitive information if
+   product owners are not careful.
 
 .. attention::
+   **MetricService::Get is a synchronous RPC method**
 
-  **MetricService::Get is a synchronous RPC method**
+   Calls to is ``MetricService::Get`` are blocking and will send all metrics
+   immediately, even though it is a server-streaming RPC. This will work fine if
+   the device doesn't have too many metrics, or doesn't have concurrent RPCs
+   like logging, but could be a problem in some cases.
 
-  Calls to is ``MetricService::Get`` are blocking and will send all metrics
-  immediately, even though it is a server-streaming RPC. This will work fine if
-  the device doesn't have too many metrics, or doesn't have concurrent RPCs
-  like logging, but could be a problem in some cases.
-
-  We plan to offer an async version where the application is responsible for
-  pumping the metrics into the streaming response. This gives flow control to
-  the application.
+   We plan to offer an async version where the application is responsible for
+   pumping the metrics into the streaming response. This gives flow control to
+   the application.
 
 -----------
 Size report
@@ -734,10 +726,9 @@
 .. include:: metric_size_report
 
 .. attention::
-
-  At time of writing, **the above sizes show an unexpectedly large flash
-  impact**. We are investigating why GCC is inserting large global static
-  constructors per group, when all the logic should be reused across objects.
+   At time of writing, **the above sizes show an unexpectedly large flash
+   impact**. We are investigating why GCC is inserting large global static
+   constructors per group, when all the logic should be reused across objects.
 
 -------------
 Metric Parser
diff --git a/pw_protobuf/docs.rst b/pw_protobuf/docs.rst
index 774cc54..fb8c129 100644
--- a/pw_protobuf/docs.rst
+++ b/pw_protobuf/docs.rst
@@ -8,9 +8,9 @@
 
 .. note::
 
-  The protobuf module is a work in progress. Wire format encoding and decoding
-  is supported, though the APIs are not final. C++ code generation exists for
-  encoding and decoding, but not yet optimized for in-memory decoding.
+   The protobuf module is a work in progress. Wire format encoding and decoding
+   is supported, though the APIs are not final. C++ code generation exists for
+   encoding and decoding, but not yet optimized for in-memory decoding.
 
 --------
 Overview
@@ -23,9 +23,9 @@
 The API is designed in three layers, which can be freely intermixed with each
 other in your code, depending on point of use requirements:
 
- 1. Message Structures,
- 2. Per-Field Writers and Readers,
- 3. Direct Writers and Readers.
+1. Message Structures,
+2. Per-Field Writers and Readers,
+3. Direct Writers and Readers.
 
 This has a few benefits. The primary one is that it allows the core proto
 serialization and deserialization libraries to be relatively small.
@@ -35,29 +35,29 @@
 To demonstrate these layers, we use the following protobuf message definition
 in the examples:
 
-.. code::
+.. code-block:: protobuf
 
-  message Customer {
-    enum Status {
-      NEW = 1;
-      ACTIVE = 2;
-      INACTIVE = 3;
-    }
-    int32 age = 1;
-    string name = 2;
-    Status status = 3;
-  }
+   message Customer {
+     enum Status {
+       NEW = 1;
+       ACTIVE = 2;
+       INACTIVE = 3;
+     }
+     int32 age = 1;
+     string name = 2;
+     Status status = 3;
+   }
 
 And the following accompanying options file:
 
-.. code::
+.. code-block:: text
 
-  Customer.name max_size:32
+   Customer.name max_size:32
 
 .. toctree::
-  :maxdepth: 1
+   :maxdepth: 1
 
-  size_report
+   size_report
 
 Message Structures
 ==================
@@ -66,50 +66,50 @@
 
 This results in the following generated structure:
 
-.. code:: c++
+.. code-block:: c++
 
-  enum class Customer::Status : uint32_t {
-    NEW = 1,
-    ACTIVE = 2,
-    INACTIVE = 3,
+   enum class Customer::Status : uint32_t {
+     NEW = 1,
+     ACTIVE = 2,
+     INACTIVE = 3,
 
-    kNew = NEW,
-    kActive = ACTIVE,
-    kInactive = INACTIVE,
-  };
+     kNew = NEW,
+     kActive = ACTIVE,
+     kInactive = INACTIVE,
+   };
 
-  struct Customer::Message {
-    int32_t age;
-    pw::InlineString<32> name;
-    Customer::Status status;
-  };
+   struct Customer::Message {
+     int32_t age;
+     pw::InlineString<32> name;
+     Customer::Status status;
+   };
 
 Which can be encoded with the code:
 
-.. code:: c++
+.. code-block:: c++
 
-  #include "example_protos/customer.pwpb.h"
+   #include "example_protos/customer.pwpb.h"
 
-  pw::Status EncodeCustomer(Customer::StreamEncoder& encoder) {
-    return encoder.Write({
-      age = 33,
-      name = "Joe Bloggs",
-      status = Customer::Status::INACTIVE
-    });
-  }
+   pw::Status EncodeCustomer(Customer::StreamEncoder& encoder) {
+     return encoder.Write({
+       age = 33,
+       name = "Joe Bloggs",
+       status = Customer::Status::INACTIVE
+     });
+   }
 
 And decoded into a struct with the code:
 
-.. code:: c++
+.. code-block:: c++
 
-  #include "example_protos/customer.pwpb.h"
+   #include "example_protos/customer.pwpb.h"
 
-  pw::Status DecodeCustomer(Customer::StreamDecoder& decoder) {
-    Customer::Message customer{};
-    PW_TRY(decoder.Read(customer));
-    // Read fields from customer
-    return pw::OkStatus();
-  }
+   pw::Status DecodeCustomer(Customer::StreamDecoder& decoder) {
+     Customer::Message customer{};
+     PW_TRY(decoder.Read(customer));
+     // Read fields from customer
+     return pw::OkStatus();
+   }
 
 These structures can be moved, copied, and compared with each other for
 equality.
@@ -130,28 +130,28 @@
 
 .. code-block:: c++
 
-  template <typename Message>
-  constexpr bool IsTriviallyComparable<Message>();
+   template <typename Message>
+   constexpr bool IsTriviallyComparable<Message>();
 
 For example, given the following protobuf definitions:
 
-.. code-block::
+.. code-block:: protobuf
 
-  message Point {
-    int32 x = 1;
-    int32 y = 2;
-  }
+   message Point {
+     int32 x = 1;
+     int32 y = 2;
+   }
 
-  message Label {
-    Point point = 1;
-    string label = 2;
-  }
+   message Label {
+     Point point = 1;
+     string label = 2;
+   }
 
 And the accompanying options file:
 
-.. code-block::
+.. code-block:: text
 
-  Label.label use_callback:true
+   Label.label use_callback:true
 
 The ``Point`` message can be fully compared for equality, but ``Label`` cannot.
 ``Label`` still defines an ``operator==``, but it ignores the ``label`` string.
@@ -172,22 +172,22 @@
 constant that represents the maximum encoded size of the protobuf message,
 excluding the contents of any field values which require a callback.
 
-.. code:: c++
+.. code-block:: c++
 
-  #include "example_protos/customer.pwpb.h"
+   #include "example_protos/customer.pwpb.h"
 
-  std::byte buffer[Customer::kMaxEncodedSizeBytes];
-  Customer::MemoryEncoder encoder(buffer);
-  const auto status = encoder.Write({
-    age = 22,
-    name = "Wolfgang Bjornson",
-    status = Customer::Status::ACTIVE
-  });
+   std::byte buffer[Customer::kMaxEncodedSizeBytes];
+   Customer::MemoryEncoder encoder(buffer);
+   const auto status = encoder.Write({
+     age = 22,
+     name = "Wolfgang Bjornson",
+     status = Customer::Status::ACTIVE
+   });
 
-  // Always check the encoder status or return values from Write calls.
-  if (!status.ok()) {
-    PW_LOG_INFO("Failed to encode proto; %s", encoder.status().str());
-  }
+   // Always check the encoder status or return values from Write calls.
+   if (!status.ok()) {
+     PW_LOG_INFO("Failed to encode proto; %s", encoder.status().str());
+   }
 
 In the above example, because the ``name`` field has a ``max_size`` specified
 in the accompanying options file, ``kMaxEncodedSizeBytes`` includes the maximum
@@ -202,54 +202,54 @@
 but is known to your code (``kMaxImageDataSize`` in this example being a
 constant in your own code), you can simply add it to the generated constant:
 
-.. code:: c++
+.. code-block:: c++
 
-  #include "example_protos/store.pwpb.h"
+   #include "example_protos/store.pwpb.h"
 
-  const std::byte image_data[kMaxImageDataSize] = { ... };
+   const std::byte image_data[kMaxImageDataSize] = { ... };
 
-  Store::Message store{};
-  // Calling SetEncoder means we must always extend the buffer size.
-  store.image_data.SetEncoder([](Store::StreamEncoder& encoder) {
-    return encoder.WriteImageData(image_data);
-  });
+   Store::Message store{};
+   // Calling SetEncoder means we must always extend the buffer size.
+   store.image_data.SetEncoder([](Store::StreamEncoder& encoder) {
+     return encoder.WriteImageData(image_data);
+   });
 
-  std::byte buffer[Store::kMaxEncodedSizeBytes + kMaxImageDataSize];
-  Store::MemoryEncoder encoder(buffer);
-  const auto status = encoder.Write(store);
+   std::byte buffer[Store::kMaxEncodedSizeBytes + kMaxImageDataSize];
+   Store::MemoryEncoder encoder(buffer);
+   const auto status = encoder.Write(store);
 
-  // Always check the encoder status or return values from Write calls.
-  if (!status.ok()) {
-    PW_LOG_INFO("Failed to encode proto; %s", encoder.status().str());
-  }
+   // Always check the encoder status or return values from Write calls.
+   if (!status.ok()) {
+     PW_LOG_INFO("Failed to encode proto; %s", encoder.status().str());
+   }
 
 Or when using a variable number of repeated submessages, where the maximum
 number is known to your code but not to the proto, you can add the constants
 from one message type to another:
 
-.. code:: c++
+.. code-block:: c++
 
-  #include "example_protos/person.pwpb.h"
+   #include "example_protos/person.pwpb.h"
 
-  Person::Message grandchild{};
-  // Calling SetEncoder means we must always extend the buffer size.
-  grandchild.grandparent.SetEncoder([](Person::StreamEncoder& encoder) {
-    PW_TRY(encoder.GetGrandparentEncoder().Write(maternal_grandma));
-    PW_TRY(encoder.GetGrandparentEncoder().Write(maternal_grandpa));
-    PW_TRY(encoder.GetGrandparentEncoder().Write(paternal_grandma));
-    PW_TRY(encoder.GetGrandparentEncoder().Write(paternal_grandpa));
-    return pw::OkStatus();
-  });
+   Person::Message grandchild{};
+   // Calling SetEncoder means we must always extend the buffer size.
+   grandchild.grandparent.SetEncoder([](Person::StreamEncoder& encoder) {
+     PW_TRY(encoder.GetGrandparentEncoder().Write(maternal_grandma));
+     PW_TRY(encoder.GetGrandparentEncoder().Write(maternal_grandpa));
+     PW_TRY(encoder.GetGrandparentEncoder().Write(paternal_grandma));
+     PW_TRY(encoder.GetGrandparentEncoder().Write(paternal_grandpa));
+     return pw::OkStatus();
+   });
 
-  std::byte buffer[Person::kMaxEncodedSizeBytes +
-                   Grandparent::kMaxEncodedSizeBytes * 4];
-  Person::MemoryEncoder encoder(buffer);
-  const auto status = encoder.Write(grandchild);
+   std::byte buffer[Person::kMaxEncodedSizeBytes +
+                    Grandparent::kMaxEncodedSizeBytes * 4];
+   Person::MemoryEncoder encoder(buffer);
+   const auto status = encoder.Write(grandchild);
 
-  // Always check the encoder status or return values from Write calls.
-  if (!status.ok()) {
-    PW_LOG_INFO("Failed to encode proto; %s", encoder.status().str());
-  }
+   // Always check the encoder status or return values from Write calls.
+   if (!status.ok()) {
+     PW_LOG_INFO("Failed to encode proto; %s", encoder.status().str());
+   }
 
 .. warning::
   Encoding to a buffer that is insufficiently large will return
@@ -273,33 +273,33 @@
 underlying methods with the correct field numbers and value types, and result
 in no additional binary code over correctly using the core implementation.
 
-.. code:: c++
+.. code-block:: c++
 
-  class Customer::StreamEncoder : pw::protobuf::StreamEncoder {
-   public:
-    // Message Structure Writer.
-    pw::Status Write(const Customer::Message&);
+   class Customer::StreamEncoder : pw::protobuf::StreamEncoder {
+    public:
+     // Message Structure Writer.
+     pw::Status Write(const Customer::Message&);
 
-    // Per-Field Typed Writers.
-    pw::Status WriteAge(int32_t);
+     // Per-Field Typed Writers.
+     pw::Status WriteAge(int32_t);
 
-    pw::Status WriteName(std::string_view);
-    pw::Status WriteName(const char*, size_t);
+     pw::Status WriteName(std::string_view);
+     pw::Status WriteName(const char*, size_t);
 
-    pw::Status WriteStatus(Customer::Status);
-  };
+     pw::Status WriteStatus(Customer::Status);
+   };
 
 So the same encoding method could be written as:
 
-.. code:: c++
+.. code-block:: c++
 
-  #include "example_protos/customer.pwpb.h"
+   #include "example_protos/customer.pwpb.h"
 
-  Status EncodeCustomer(Customer::StreamEncoder& encoder) {
-    PW_TRY(encoder.WriteAge(33));
-    PW_TRY(encoder.WriteName("Joe Bloggs"sv));
-    PW_TRY(encoder.WriteStatus(Customer::Status::INACTIVE));
-  }
+   Status EncodeCustomer(Customer::StreamEncoder& encoder) {
+     PW_TRY(encoder.WriteAge(33));
+     PW_TRY(encoder.WriteName("Joe Bloggs"sv));
+     PW_TRY(encoder.WriteStatus(Customer::Status::INACTIVE));
+   }
 
 Pigweed's protobuf encoders encode directly to the wire format of a proto rather
 than staging information to a mutable datastructure. This means any writes of a
@@ -319,69 +319,69 @@
 
 For example:
 
-.. code::
+.. code-block:: protobuf
 
-  // The first half of the overlaid message.
-  message BaseMessage {
-    uint32 length = 1;
-    reserved 2;  // Reserved for Overlay
-  }
+   // The first half of the overlaid message.
+   message BaseMessage {
+     uint32 length = 1;
+     reserved 2;  // Reserved for Overlay
+   }
 
-  // OK: The second half of the overlaid message.
-  message Overlay {
-    reserved 1;  // Reserved for BaseMessage
-    uint32 height = 2;
-  }
+   // OK: The second half of the overlaid message.
+   message Overlay {
+     reserved 1;  // Reserved for BaseMessage
+     uint32 height = 2;
+   }
 
-  // OK: A message that overlays and bundles both types together.
-  message Both {
-    uint32 length = 1;  // Defined independently by BaseMessage
-    uint32 height = 2;  // Defined independently by Overlay
-  }
+   // OK: A message that overlays and bundles both types together.
+   message Both {
+     uint32 length = 1;  // Defined independently by BaseMessage
+     uint32 height = 2;  // Defined independently by Overlay
+   }
 
-  // BAD: Diverges from BaseMessage's definition, and can cause decode
-  // errors/corruption.
-  message InvalidOverlay {
-    fixed32 length = 1;
-  }
+   // BAD: Diverges from BaseMessage's definition, and can cause decode
+   // errors/corruption.
+   message InvalidOverlay {
+     fixed32 length = 1;
+   }
 
 The ``StreamEncoderCast<>()`` helper template reduces very messy casting into
 a much easier to read syntax:
 
-.. code:: c++
+.. code-block:: c++
 
-  #include "pw_protobuf/encoder.h"
-  #include "pw_protobuf_test_protos/full_test.pwpb.h"
+   #include "pw_protobuf/encoder.h"
+   #include "pw_protobuf_test_protos/full_test.pwpb.h"
 
-  Result<ConstByteSpan> EncodeOverlaid(uint32_t height,
-                                       uint32_t length,
-                                       ConstByteSpan encode_buffer) {
-    BaseMessage::MemoryEncoder base(encode_buffer);
+   Result<ConstByteSpan> EncodeOverlaid(uint32_t height,
+                                        uint32_t length,
+                                        ConstByteSpan encode_buffer) {
+     BaseMessage::MemoryEncoder base(encode_buffer);
 
-    // Without StreamEncoderCast<>(), this line would be:
-    //   Overlay::StreamEncoder& overlay =
-    //       *static_cast<Overlay::StreamEncoder*>(
-    //           static_cast<pw::protobuf::StreamEncoder*>(&base)
-    Overlay::StreamEncoder& overlay =
-        StreamEncoderCast<Overlay::StreamEncoder>(base);
-    if (!overlay.WriteHeight(height).ok()) {
-      return overlay.status();
-    }
-    if (!base.WriteLength(length).ok()) {
-      return base.status();
-    }
-    return ConstByteSpan(base);
-  }
+     // Without StreamEncoderCast<>(), this line would be:
+     //   Overlay::StreamEncoder& overlay =
+     //       *static_cast<Overlay::StreamEncoder*>(
+     //           static_cast<pw::protobuf::StreamEncoder*>(&base)
+     Overlay::StreamEncoder& overlay =
+         StreamEncoderCast<Overlay::StreamEncoder>(base);
+     if (!overlay.WriteHeight(height).ok()) {
+       return overlay.status();
+     }
+     if (!base.WriteLength(length).ok()) {
+       return base.status();
+     }
+     return ConstByteSpan(base);
+   }
 
 While this use case is somewhat uncommon, it's a core supported use case of
 pw_protobuf.
 
 .. warning::
 
-  Using this to convert one stream encoder to another when the messages
-  themselves do not safely overlay will result in corrupt protos. Be careful
-  when doing this as there's no compile-time way to detect whether or not two
-  messages are meant to overlay.
+   Using this to convert one stream encoder to another when the messages
+   themselves do not safely overlay will result in corrupt protos. Be careful
+   when doing this as there's no compile-time way to detect whether or not two
+   messages are meant to overlay.
 
 Decoding
 --------
@@ -389,62 +389,62 @@
 structure, the following additional methods are also generated in the typed
 ``StreamDecoder`` class.
 
-.. code:: c++
+.. code-block:: c++
 
-  class Customer::StreamDecoder : pw::protobuf::StreamDecoder {
-   public:
-    // Message Structure Reader.
-    pw::Status Read(Customer::Message&);
+   class Customer::StreamDecoder : pw::protobuf::StreamDecoder {
+    public:
+     // Message Structure Reader.
+     pw::Status Read(Customer::Message&);
 
-    // Returns the identity of the current field.
-    ::pw::Result<Fields> Field();
+     // Returns the identity of the current field.
+     ::pw::Result<Fields> Field();
 
-    // Per-Field Typed Readers.
-    pw::Result<int32_t> ReadAge();
+     // Per-Field Typed Readers.
+     pw::Result<int32_t> ReadAge();
 
-    pw::StatusWithSize ReadName(pw::span<char>);
-    BytesReader GetNameReader(); // Read name as a stream of bytes.
+     pw::StatusWithSize ReadName(pw::span<char>);
+     BytesReader GetNameReader(); // Read name as a stream of bytes.
 
-    pw::Result<Customer::Status> ReadStatus();
-  };
+     pw::Result<Customer::Status> ReadStatus();
+   };
 
 Complete and correct decoding requires looping through the fields, so is more
 complex than encoding or using the message structure.
 
-.. code:: c++
+.. code-block:: c++
 
-  pw::Status DecodeCustomer(Customer::StreamDecoder& decoder) {
-    uint32_t age;
-    char name[32];
-    Customer::Status status;
+   pw::Status DecodeCustomer(Customer::StreamDecoder& decoder) {
+     uint32_t age;
+     char name[32];
+     Customer::Status status;
 
-    while ((status = decoder.Next()).ok()) {
-      switch (decoder.Field().value()) {
-        case Customer::Fields::kAge: {
-          PW_TRY_ASSIGN(age, decoder.ReadAge());
-          break;
-        }
-        case Customer::Fields::kName: {
-          PW_TRY(decoder.ReadName(name));
-          break;
-        }
-        case Customer::Fields::kStatus: {
-          PW_TRY_ASSIGN(status, decoder.ReadStatus());
-          break;
-        }
-      }
-    }
+     while ((status = decoder.Next()).ok()) {
+       switch (decoder.Field().value()) {
+         case Customer::Fields::kAge: {
+           PW_TRY_ASSIGN(age, decoder.ReadAge());
+           break;
+         }
+         case Customer::Fields::kName: {
+           PW_TRY(decoder.ReadName(name));
+           break;
+         }
+         case Customer::Fields::kStatus: {
+           PW_TRY_ASSIGN(status, decoder.ReadStatus());
+           break;
+         }
+       }
+     }
 
-    return status.IsOutOfRange() ? OkStatus() : status;
-  }
+     return status.IsOutOfRange() ? OkStatus() : status;
+   }
 
 .. warning:: ``Fields::SNAKE_CASE`` is deprecated. Use ``Fields::kCamelCase``.
 
-  Transitional support for ``Fields::SNAKE_CASE`` will soon only be available by
-  explicitly setting the following GN variable in your project:
-  ``pw_protobuf_compiler_GENERATE_LEGACY_ENUM_SNAKE_CASE_NAMES=true``
+   Transitional support for ``Fields::SNAKE_CASE`` will soon only be available by
+   explicitly setting the following GN variable in your project:
+   ``pw_protobuf_compiler_GENERATE_LEGACY_ENUM_SNAKE_CASE_NAMES=true``
 
-  This support will be removed after downstream projects have been migrated.
+   This support will be removed after downstream projects have been migrated.
 
 
 Reading a single field
@@ -456,52 +456,52 @@
 
 .. code-block:: c++
 
-  pw::Status ReadCustomerData(pw::ConstByteSpan serialized_customer) {
-    pw::Result<uint32_t> age = Customer::FindAge(serialized_customer);
-    if (!age.ok()) {
-      return age.status();
-    }
+   pw::Status ReadCustomerData(pw::ConstByteSpan serialized_customer) {
+     pw::Result<uint32_t> age = Customer::FindAge(serialized_customer);
+     if (!age.ok()) {
+       return age.status();
+     }
 
-    // This will scan the buffer again from the start, which is less efficient
-    // than writing a custom decoder loop.
-    pw::Result<std::string_view> name = Customer::FindName(serialized_customer);
-    if (!age.ok()) {
-      return age.status();
-    }
+     // This will scan the buffer again from the start, which is less efficient
+     // than writing a custom decoder loop.
+     pw::Result<std::string_view> name = Customer::FindName(serialized_customer);
+     if (!age.ok()) {
+       return age.status();
+     }
 
-    DoStuff(age, name);
-    return pw::OkStatus();
-  }
+     DoStuff(age, name);
+     return pw::OkStatus();
+   }
 
 The ``Find`` APIs also work with streamed data, as shown below.
 
 .. code-block:: c++
 
-  pw::Status ReadCustomerData(pw::stream::Reader& customer_stream) {
-    pw::Result<uint32_t> age = Customer::FindAge(customer_stream);
-    if (!age.ok()) {
-      return age.status();
-    }
+   pw::Status ReadCustomerData(pw::stream::Reader& customer_stream) {
+     pw::Result<uint32_t> age = Customer::FindAge(customer_stream);
+     if (!age.ok()) {
+       return age.status();
+     }
 
-    // This will begin scanning for `name` from the current position of the
-    // stream (following the `age` field). If `name` appeared before `age` in
-    // the serialized data, it will not be found.
-    //
-    // Note that unlike with the buffer APIs, stream Find methods copy `string`
-    // and `bytes` fields into a user-provided buffer.
-    char name[32];
-    pw::StatusWithSize sws = Customer::FindName(serialized_customer, name);
-    if (!sws.ok()) {
-      return sws.status();
-    }
-    if (sws.size() >= sizeof(name)) {
-      return pw::Status::OutOfRange();
-    }
-    name[sws.size()] = '\0';
+     // This will begin scanning for `name` from the current position of the
+     // stream (following the `age` field). If `name` appeared before `age` in
+     // the serialized data, it will not be found.
+     //
+     // Note that unlike with the buffer APIs, stream Find methods copy `string`
+     // and `bytes` fields into a user-provided buffer.
+     char name[32];
+     pw::StatusWithSize sws = Customer::FindName(serialized_customer, name);
+     if (!sws.ok()) {
+       return sws.status();
+     }
+     if (sws.size() >= sizeof(name)) {
+       return pw::Status::OutOfRange();
+     }
+     name[sws.size()] = '\0';
 
-    DoStuff(age, name);
-    return pw::OkStatus();
-  }
+     DoStuff(age, name);
+     return pw::OkStatus();
+   }
 
 .. note::
 
@@ -529,37 +529,37 @@
 To encode the same message we've used in the examples thus far, we would use
 the following parts of the core API:
 
-.. code:: c++
+.. code-block:: c++
 
-  class pw::protobuf::StreamEncoder {
-   public:
-    Status WriteInt32(uint32_t field_number, int32_t);
-    Status WriteUint32(uint32_t field_number, uint32_t);
+   class pw::protobuf::StreamEncoder {
+    public:
+     Status WriteInt32(uint32_t field_number, int32_t);
+     Status WriteUint32(uint32_t field_number, uint32_t);
 
-    Status WriteString(uint32_t field_number, std::string_view);
-    Status WriteString(uint32_t field_number, const char*, size_t);
+     Status WriteString(uint32_t field_number, std::string_view);
+     Status WriteString(uint32_t field_number, const char*, size_t);
 
-    // And many other methods, see pw_protobuf/encoder.h
-  };
+     // And many other methods, see pw_protobuf/encoder.h
+   };
 
 Encoding the same message requires that we specify the field numbers, which we
 can hardcode, or supplement using the C++ code generated ``Fields`` enum, and
 cast the enumerated type.
 
-.. code:: c++
+.. code-block:: c++
 
-  #include "pw_protobuf/encoder.h"
-  #include "example_protos/customer.pwpb.h"
+   #include "pw_protobuf/encoder.h"
+   #include "example_protos/customer.pwpb.h"
 
-  Status EncodeCustomer(pw::protobuf::StreamEncoder& encoder) {
-    PW_TRY(encoder.WriteInt32(static_cast<uint32_t>(Customer::Fields::kAge),
-                              33));
-    PW_TRY(encoder.WriteString(static_cast<uint32_t>(Customer::Fields::kName),
-                               "Joe Bloggs"sv));
-    PW_TRY(encoder.WriteUint32(
-        static_cast<uint32_t>(Customer::Fields::kStatus),
-        static_cast<uint32_t>(Customer::Status::INACTIVE)));
-  }
+   Status EncodeCustomer(pw::protobuf::StreamEncoder& encoder) {
+     PW_TRY(encoder.WriteInt32(static_cast<uint32_t>(Customer::Fields::kAge),
+                               33));
+     PW_TRY(encoder.WriteString(static_cast<uint32_t>(Customer::Fields::kName),
+                                "Joe Bloggs"sv));
+     PW_TRY(encoder.WriteUint32(
+         static_cast<uint32_t>(Customer::Fields::kStatus),
+         static_cast<uint32_t>(Customer::Status::INACTIVE)));
+   }
 
 Decoding
 --------
@@ -568,52 +568,52 @@
 
 To decode the same message we would use the following parts of the core API:
 
-.. code:: c++
+.. code-block:: c++
 
-  class pw::protobuf::StreamDecoder {
-   public:
-    // Returns the identity of the current field.
-    ::pw::Result<uint32_t> FieldNumber();
+   class pw::protobuf::StreamDecoder {
+    public:
+     // Returns the identity of the current field.
+     ::pw::Result<uint32_t> FieldNumber();
 
-    Result<int32_t> ReadInt32();
-    Result<uint32_t> ReadUint32();
+     Result<int32_t> ReadInt32();
+     Result<uint32_t> ReadUint32();
 
-    StatusWithSize ReadString(pw::span<char>);
+     StatusWithSize ReadString(pw::span<char>);
 
-    // And many other methods, see pw_protobuf/stream_decoder.h
-  };
+     // And many other methods, see pw_protobuf/stream_decoder.h
+   };
 
 As with the typed per-field API, complete and correct decoding requires looping
 through the fields and checking the field numbers, along with casting types.
 
-.. code:: c++
+.. code-block:: c++
 
-  pw::Status DecodeCustomer(pw::protobuf::StreamDecoder& decoder) {
-    uint32_t age;
-    char name[32];
-    Customer::Status status;
+   pw::Status DecodeCustomer(pw::protobuf::StreamDecoder& decoder) {
+     uint32_t age;
+     char name[32];
+     Customer::Status status;
 
-    while ((status = decoder.Next()).ok()) {
-      switch (decoder.FieldNumber().value()) {
-        case static_cast<uint32_t>(Customer::Fields::kAge): {
-          PW_TRY_ASSIGN(age, decoder.ReadInt32());
-          break;
-        }
-        case static_cast<uint32_t>(Customer::Fields::kName): {
-          PW_TRY(decoder.ReadString(name));
-          break;
-        }
-        case static_cast<uint32_t>(Customer::Fields::kStatus): {
-          uint32_t status_value;
-          PW_TRY_ASSIGN(status_value, decoder.ReadUint32());
-          status = static_cast<Customer::Status>(status_value);
-          break;
-        }
-      }
-    }
+     while ((status = decoder.Next()).ok()) {
+       switch (decoder.FieldNumber().value()) {
+         case static_cast<uint32_t>(Customer::Fields::kAge): {
+           PW_TRY_ASSIGN(age, decoder.ReadInt32());
+           break;
+         }
+         case static_cast<uint32_t>(Customer::Fields::kName): {
+           PW_TRY(decoder.ReadString(name));
+           break;
+         }
+         case static_cast<uint32_t>(Customer::Fields::kStatus): {
+           uint32_t status_value;
+           PW_TRY_ASSIGN(status_value, decoder.ReadUint32());
+           status = static_cast<Customer::Status>(status_value);
+           break;
+         }
+       }
+     }
 
-    return status.IsOutOfRange() ? OkStatus() : status;
-  }
+     return status.IsOutOfRange() ? OkStatus() : status;
+   }
 
 Find APIs
 ---------
@@ -655,29 +655,29 @@
 
 Example ``BUILD.gn``:
 
-.. code::
+.. code-block::
 
-  import("//build_overrides/pigweed.gni")
+   import("//build_overrides/pigweed.gni")
 
-  import("$dir_pw_build/target_types.gni")
-  import("$dir_pw_protobuf_compiler/proto.gni")
+   import("$dir_pw_build/target_types.gni")
+   import("$dir_pw_protobuf_compiler/proto.gni")
 
-  # This target controls where the *.pwpb.h headers end up on the include path.
-  # In this example, it's at "pet_daycare_protos/client.pwpb.h".
-  pw_proto_library("pet_daycare_protos") {
-    sources = [
-      "pet_daycare_protos/client.proto",
-    ]
-  }
+   # This target controls where the *.pwpb.h headers end up on the include path.
+   # In this example, it's at "pet_daycare_protos/client.pwpb.h".
+   pw_proto_library("pet_daycare_protos") {
+     sources = [
+       "pet_daycare_protos/client.proto",
+     ]
+   }
 
-  pw_source_set("example_client") {
-    sources = [ "example_client.cc" ]
-    deps = [
-      ":pet_daycare_protos.pwpb",
-      dir_pw_bytes,
-      dir_pw_stream,
-    ]
-  }
+   pw_source_set("example_client") {
+     sources = [ "example_client.cc" ]
+     deps = [
+       ":pet_daycare_protos.pwpb",
+       dir_pw_bytes,
+       dir_pw_stream,
+     ]
+   }
 
 -------------
 Configuration
@@ -725,13 +725,13 @@
 host software can use the reflection API to query for the options and validate
 messages comply with the specified limitations.
 
-.. code::
+.. code-block:: text
 
-  import "pw_protobuf_protos/field_options.proto";
+   import "pw_protobuf_protos/field_options.proto";
 
-  message Demo {
-    string size_limited_string = 1 [(pw.protobuf.pwpb).max_size = 16];
-  };
+   message Demo {
+     string size_limited_string = 1 [(pw.protobuf.pwpb).max_size = 16];
+   };
 
 Options Files
 =============
@@ -744,30 +744,30 @@
 
 Example:
 
-.. code::
+.. code-block::
 
-  // Set an option for a specific field.
-  fuzzy_friends.Client.visit_dates max_count:16
+   // Set an option for a specific field.
+   fuzzy_friends.Client.visit_dates max_count:16
 
-  // Set options for multiple fields by wildcard matching.
-  fuzzy_friends.Pet.* max_size:32
+   // Set options for multiple fields by wildcard matching.
+   fuzzy_friends.Pet.* max_size:32
 
-  // Set multiple options in one go.
-  fuzzy_friends.Dog.paws max_count:4 fixed_count:true
+   // Set multiple options in one go.
+   fuzzy_friends.Dog.paws max_count:4 fixed_count:true
 
 Options files should be listed as ``inputs`` when defining ``pw_proto_library``,
 e.g.
 
-.. code::
+.. code-block::
 
-  pw_proto_library("pet_daycare_protos") {
-    sources = [
-      "pet_daycare_protos/client.proto",
-    ]
-    inputs = [
-      "pet_daycare_protos/client.options",
-    ]
-  }
+   pw_proto_library("pet_daycare_protos") {
+     sources = [
+       "pet_daycare_protos/client.proto",
+     ]
+     inputs = [
+       "pet_daycare_protos/client.options",
+     ]
+   }
 
 Valid options are:
 
@@ -820,177 +820,177 @@
 
 * Scalar fields are represented by their appropriate C++ type.
 
-  .. code::
+  .. code-block:: protobuf
 
-    message Customer {
-      int32 age = 1;
-      uint32 birth_year = 2;
-      sint64 rating = 3;
-      bool is_active = 4;
-    }
+     message Customer {
+       int32 age = 1;
+       uint32 birth_year = 2;
+       sint64 rating = 3;
+       bool is_active = 4;
+     }
 
-  .. code:: c++
+  .. code-block:: c++
 
-    struct Customer::Message {
-      int32_t age;
-      uint32_t birth_year;
-      int64_t rating;
-      bool is_active;
-    };
+     struct Customer::Message {
+       int32_t age;
+       uint32_t birth_year;
+       int64_t rating;
+       bool is_active;
+     };
 
 * Enumerations are represented by a code generated namespaced proto enum.
 
-  .. code::
+  .. code-block:: protobuf
 
-    message Award {
-      enum Service {
-        BRONZE = 1;
-        SILVER = 2;
-        GOLD = 3;
-      }
-      Service service = 1;
-    }
+     message Award {
+       enum Service {
+         BRONZE = 1;
+         SILVER = 2;
+         GOLD = 3;
+       }
+       Service service = 1;
+     }
 
-  .. code:: c++
+  .. code-block:: c++
 
-    enum class Award::Service : uint32_t {
-      BRONZE = 1,
-      SILVER = 2,
-      GOLD = 3,
+     enum class Award::Service : uint32_t {
+       BRONZE = 1,
+       SILVER = 2,
+       GOLD = 3,
 
-      kBronze = BRONZE,
-      kSilver = SILVER,
-      kGold = GOLD,
-    };
+       kBronze = BRONZE,
+       kSilver = SILVER,
+       kGold = GOLD,
+     };
 
-    struct Award::Message {
-      Award::Service service;
-    };
+     struct Award::Message {
+       Award::Service service;
+     };
 
   Aliases to the enum values are also included in the "constant" style to match
   your preferred coding style. These aliases have any common prefix to the
   enumeration values removed, such that:
 
-  .. code::
+  .. code-block:: protobuf
 
-    enum Activity {
-      ACTIVITY_CYCLING = 1;
-      ACTIVITY_RUNNING = 2;
-      ACTIVITY_SWIMMING = 3;
-    }
+     enum Activity {
+       ACTIVITY_CYCLING = 1;
+       ACTIVITY_RUNNING = 2;
+       ACTIVITY_SWIMMING = 3;
+     }
 
-  .. code:: c++
+  .. code-block:: c++
 
-    enum class Activity : uint32_t {
-      ACTIVITY_CYCLING = 1,
-      ACTIVITY_RUNNING = 2,
-      ACTIVITY_SWIMMING = 3,
+     enum class Activity : uint32_t {
+       ACTIVITY_CYCLING = 1,
+       ACTIVITY_RUNNING = 2,
+       ACTIVITY_SWIMMING = 3,
 
-      kCycling = ACTIVITY_CYCLING,
-      kRunning = ACTIVITY_RUNNING,
-      kSwimming = ACTIVITY_SWIMMING,
-    };
+       kCycling = ACTIVITY_CYCLING,
+       kRunning = ACTIVITY_RUNNING,
+       kSwimming = ACTIVITY_SWIMMING,
+     };
 
 
 * Nested messages are represented by their own ``struct Message`` provided that
   a reference cycle does not exist.
 
-  .. code::
+  .. code-block:: protobuf
 
-    message Sale {
-      Customer customer = 1;
-      Product product = 2;
-    }
+     message Sale {
+       Customer customer = 1;
+       Product product = 2;
+     }
 
-  .. code:: c++
+  .. code-block:: c++
 
-    struct Sale::Message {
-      Customer::Message customer;
-      Product::Message product;
-    };
+     struct Sale::Message {
+       Customer::Message customer;
+       Product::Message product;
+     };
 
 * Optional scalar fields are represented by the appropriate C++ type wrapped in
   ``std::optional``. Optional fields are not encoded when the value is not
   present.
 
-  .. code::
+  .. code-block:: protobuf
 
-    message Loyalty {
-      optional int32 points = 1;
-    }
+     message Loyalty {
+       optional int32 points = 1;
+     }
 
-  .. code:: c++
+  .. code-block:: c++
 
-    struct Loyalty::Message {
-      std::optional<int32_t> points;
-    };
+     struct Loyalty::Message {
+       std::optional<int32_t> points;
+     };
 
 * Repeated scalar fields are represented by ``pw::Vector`` when the
   ``max_count`` option is set for that field, or by ``std::array`` when both
   ``max_count`` and ``fixed_count:true`` are set.
 
-  .. code::
+  .. code-block:: protobuf
 
     message Register {
       repeated int32 cash_in = 1;
       repeated int32 cash_out = 2;
     }
 
-  .. code::
+  .. code-block:: text
 
-    Register.cash_in max_count:32 fixed_count:true
-    Register.cash_out max_count:64
+     Register.cash_in max_count:32 fixed_count:true
+     Register.cash_out max_count:64
 
-  .. code:: c++
+  .. code-block:: c++
 
-    struct Register::Message {
-      std::array<int32_t, 32> cash_in;
-      pw::Vector<int32_t, 64> cash_out;
-    };
+     struct Register::Message {
+       std::array<int32_t, 32> cash_in;
+       pw::Vector<int32_t, 64> cash_out;
+     };
 
 * `bytes` fields are represented by ``pw::Vector`` when the ``max_size`` option
   is set for that field, or by ``std::array`` when both ``max_size`` and
   ``fixed_size:true`` are set.
 
-  .. code::
+  .. code-block:: protobuf
 
-    message Product {
-      bytes sku = 1;
-      bytes serial_number = 2;
-    }
+     message Product {
+       bytes sku = 1;
+       bytes serial_number = 2;
+     }
 
-  .. code::
+  .. code-block:: text
 
-    Product.sku max_size:8 fixed_size:true
-    Product.serial_number max_size:64
+     Product.sku max_size:8 fixed_size:true
+     Product.serial_number max_size:64
 
-  .. code:: c++
+  .. code-block:: c++
 
-    struct Product::Message {
-      std::array<std::byte, 8> sku;
-      pw::Vector<std::byte, 64> serial_number;
-    };
+     struct Product::Message {
+       std::array<std::byte, 8> sku;
+       pw::Vector<std::byte, 64> serial_number;
+     };
 
 * `string` fields are represented by a :cpp:type:`pw::InlineString` when the
   ``max_size`` option is set for that field. The string can hold up to
   ``max_size`` characters, and is always null terminated. The null terminator is
   not counted in ``max_size``.
 
-  .. code::
+  .. code-block:: protobuf
 
-    message Employee {
-      string name = 1;
-    }
+     message Employee {
+       string name = 1;
+     }
 
-  .. code::
+  .. code-block:: text
 
-    Employee.name max_size:128
+     Employee.name max_size:128
 
-  .. code:: c++
+  .. code-block:: c++
 
-    struct Employee::Message {
-      pw::InlineString<128> name;
-    };
+     struct Employee::Message {
+       pw::InlineString<128> name;
+     };
 
 * Nested messages with a dependency cycle, repeated scalar fields without a
   ``max_count`` option set, `bytes` and `strings` fields without a ``max_size``
@@ -1000,29 +1000,29 @@
   You set the callback to a custom function for encoding or decoding
   before passing the structure to ``Write()`` or ``Read()`` appropriately.
 
-  .. code::
+  .. code-block:: protobuf
 
-    message Store {
-      Store nearest_store = 1;
-      repeated int32 employee_numbers = 2;
-      string driections = 3;
-      repeated string address = 4;
-      repeated Employee employees = 5;
-    }
+     message Store {
+       Store nearest_store = 1;
+       repeated int32 employee_numbers = 2;
+       string driections = 3;
+       repeated string address = 4;
+       repeated Employee employees = 5;
+     }
 
-  .. code::
+  .. code-block::
 
-    // No options set.
+     // No options set.
 
-  .. code:: c++
+  .. code-block:: c++
 
-    struct Store::Message {
-      pw::protobuf::Callback<Store::StreamEncoder, Store::StreamDecoder> nearest_store;
-      pw::protobuf::Callback<Store::StreamEncoder, Store::StreamDecoder> employee_numbers;
-      pw::protobuf::Callback<Store::StreamEncoder, Store::StreamDecoder> directions;
-      pw::protobuf::Callback<Store::StreamEncoder, Store::StreamDecoder> address;
-      pw::protobuf::Callback<Store::StreamEncoder, Store::StreamDecoder> employees;
-    };
+     struct Store::Message {
+       pw::protobuf::Callback<Store::StreamEncoder, Store::StreamDecoder> nearest_store;
+       pw::protobuf::Callback<Store::StreamEncoder, Store::StreamDecoder> employee_numbers;
+       pw::protobuf::Callback<Store::StreamEncoder, Store::StreamDecoder> directions;
+       pw::protobuf::Callback<Store::StreamEncoder, Store::StreamDecoder> address;
+       pw::protobuf::Callback<Store::StreamEncoder, Store::StreamDecoder> employees;
+     };
 
   A Callback object can be converted to a ``bool`` indicating whether a callback
   is set.
@@ -1043,21 +1043,21 @@
 ``Channel::Message::operator_`` to avoid conflicting with the ``operator``
 keyword.
 
-.. code::
+.. code-block:: protobuf
 
-  message Channel {
-    int32 bitrate = 1;
-    float signal_to_noise_ratio = 2;
-    Company operator = 3;
-  }
+   message Channel {
+     int32 bitrate = 1;
+     float signal_to_noise_ratio = 2;
+     Company operator = 3;
+   }
 
-.. code:: c++
+.. code-block:: c++
 
-  struct Channel::Message {
-    int32_t bitrate;
-    float signal_to_noise_ratio;
-    Company::Message operator_;
-  };
+   struct Channel::Message {
+     int32_t bitrate;
+     float signal_to_noise_ratio;
+     Company::Message operator_;
+   };
 
 Similarly, as shown in the example below, some POSIX-signal names conflict with
 macros defined by the standard-library header ``<csignal>`` and therefore
@@ -1068,136 +1068,135 @@
 naming conflicts caused by user-defined macros are the user's responsibility
 (https://google.github.io/styleguide/cppguide.html#Preprocessor_Macros).
 
-.. code::
+.. code-block:: protobuf
 
-  enum PosixSignal {
-    NONE = 0;
-    SIGHUP = 1;
-    SIGINT = 2;
-    SIGQUIT = 3;
-    SIGILL = 4;
-    SIGTRAP = 5;
-    SIGABRT = 6;
-    SIGFPE = 8;
-    SIGKILL = 9;
-    SIGSEGV = 11;
-    SIGPIPE = 13;
-    SIGALRM = 14;
-    SIGTERM = 15;
-  }
+   enum PosixSignal {
+     NONE = 0;
+     SIGHUP = 1;
+     SIGINT = 2;
+     SIGQUIT = 3;
+     SIGILL = 4;
+     SIGTRAP = 5;
+     SIGABRT = 6;
+     SIGFPE = 8;
+     SIGKILL = 9;
+     SIGSEGV = 11;
+     SIGPIPE = 13;
+     SIGALRM = 14;
+     SIGTERM = 15;
+   }
 
-.. code:: c++
+.. code-block:: c++
 
-  enum class PosixSignal : uint32_t {
-    NONE = 0,
-    SIGHUP = 1,
-    SIGINT_ = 2,
-    SIGQUIT = 3,
-    SIGILL_ = 4,
-    SIGTRAP = 5,
-    SIGABRT_ = 6,
-    SIGFPE_ = 8,
-    SIGKILL = 9,
-    SIGSEGV_ = 11,
-    SIGPIPE = 13,
-    SIGALRM = 14,
-    SIGTERM_ = 15,
+   enum class PosixSignal : uint32_t {
+     NONE = 0,
+     SIGHUP = 1,
+     SIGINT_ = 2,
+     SIGQUIT = 3,
+     SIGILL_ = 4,
+     SIGTRAP = 5,
+     SIGABRT_ = 6,
+     SIGFPE_ = 8,
+     SIGKILL = 9,
+     SIGSEGV_ = 11,
+     SIGPIPE = 13,
+     SIGALRM = 14,
+     SIGTERM_ = 15,
 
-    kNone = NONE,
-    kSighup = SIGHUP,
-    kSigint = SIGINT_,
-    kSigquit = SIGQUIT,
-    kSigill = SIGILL_,
-    kSigtrap = SIGTRAP,
-    kSigabrt = SIGABRT_,
-    kSigfpe = SIGFPE_,
-    kSigkill = SIGKILL,
-    kSigsegv = SIGSEGV_,
-    kSigpipe = SIGPIPE,
-    kSigalrm = SIGALRM,
-    kSigterm = SIGTERM_,
-  };
+     kNone = NONE,
+     kSighup = SIGHUP,
+     kSigint = SIGINT_,
+     kSigquit = SIGQUIT,
+     kSigill = SIGILL_,
+     kSigtrap = SIGTRAP,
+     kSigabrt = SIGABRT_,
+     kSigfpe = SIGFPE_,
+     kSigkill = SIGKILL,
+     kSigsegv = SIGSEGV_,
+     kSigpipe = SIGPIPE,
+     kSigalrm = SIGALRM,
+     kSigterm = SIGTERM_,
+   };
 
 Much like reserved words and macros, the names ``Message`` and ``Fields`` are
 suffixed with underscores in generated C++ code. This is to prevent name
 conflicts with the codegen internals if they're used in a nested context as in
 the example below.
 
-.. code::
+.. code-block:: protobuf
 
-  message Function {
-    message Message {
-      string content = 1;
-    }
+   message Function {
+     message Message {
+       string content = 1;
+     }
 
-    enum Fields {
-      NONE = 0;
-      COMPLEX_NUMBERS = 1;
-      INTEGERS_MOD_5 = 2;
-      MEROMORPHIC_FUNCTIONS_ON_COMPLEX_PLANE = 3;
-      OTHER = 4;
-    }
+     enum Fields {
+       NONE = 0;
+       COMPLEX_NUMBERS = 1;
+       INTEGERS_MOD_5 = 2;
+       MEROMORPHIC_FUNCTIONS_ON_COMPLEX_PLANE = 3;
+       OTHER = 4;
+     }
 
-    Message description = 1;
-    Fields domain = 2;
-    Fields codomain = 3;
-  }
+     Message description = 1;
+     Fields domain = 2;
+     Fields codomain = 3;
+   }
 
-.. code::
+.. code-block::
 
-  Function.Message.content max_size:128
+   Function.Message.content max_size:128
 
-.. code:: c++
+.. code-block:: c++
 
-  struct Function::Message_::Message {
-    pw::InlineString<128> content;
-  };
+   struct Function::Message_::Message {
+     pw::InlineString<128> content;
+   };
 
-  enum class Function::Message_::Fields : uint32_t {
-    CONTENT = 1,
-  };
+   enum class Function::Message_::Fields : uint32_t {
+     CONTENT = 1,
+   };
 
-  enum class Function::Fields_ uint32_t {
-    NONE = 0,
-    COMPLEX_NUMBERS = 1,
-    INTEGERS_MOD_5 = 2,
-    MEROMORPHIC_FUNCTIONS_ON_COMPLEX_PLANE = 3,
-    OTHER = 4,
+   enum class Function::Fields_ uint32_t {
+     NONE = 0,
+     COMPLEX_NUMBERS = 1,
+     INTEGERS_MOD_5 = 2,
+     MEROMORPHIC_FUNCTIONS_ON_COMPLEX_PLANE = 3,
+     OTHER = 4,
 
-    kNone = NONE,
-    kComplexNumbers = COMPLEX_NUMBERS,
-    kIntegersMod5 = INTEGERS_MOD_5,
-    kMeromorphicFunctionsOnComplexPlane =
-        MEROMORPHIC_FUNCTIONS_ON_COMPLEX_PLANE,
-    kOther = OTHER,
-  };
+     kNone = NONE,
+     kComplexNumbers = COMPLEX_NUMBERS,
+     kIntegersMod5 = INTEGERS_MOD_5,
+     kMeromorphicFunctionsOnComplexPlane =
+         MEROMORPHIC_FUNCTIONS_ON_COMPLEX_PLANE,
+     kOther = OTHER,
+   };
 
-  struct Function::Message {
-    Function::Message_::Message description;
-    Function::Fields_ domain;
-    Function::Fields_ codomain;
-  };
+   struct Function::Message {
+     Function::Message_::Message description;
+     Function::Fields_ domain;
+     Function::Fields_ codomain;
+   };
 
-  enum class Function::Fields : uint32_t {
-    DESCRIPTION = 1,
-    DOMAIN = 2,
-    CODOMAIN = 3,
-  };
+   enum class Function::Fields : uint32_t {
+     DESCRIPTION = 1,
+     DOMAIN = 2,
+     CODOMAIN = 3,
+   };
 
 .. warning::
-  Note that the C++ spec also reserves two categories of identifiers for the
-  compiler to use in ways that may conflict with generated code:
+   Note that the C++ spec also reserves two categories of identifiers for the
+   compiler to use in ways that may conflict with generated code:
 
-  * Any identifier that contains two consecutive underscores anywhere in it.
+   * Any identifier that contains two consecutive underscores anywhere in it.
+   * Any identifier that starts with an underscore followed by a capital letter.
 
-  * Any identifier that starts with an underscore followed by a capital letter.
-
-  Appending underscores to symbols in these categories wouldn't change the fact
-  that they match patterns reserved for the compiler, so the codegen does not
-  currently attempt to fix them. Such names will therefore result in
-  non-portable code that may or may not work depending on the compiler. These
-  naming patterns are of course strongly discouraged in any protobufs that will
-  be used with ``pw_protobuf`` codegen.
+   Appending underscores to symbols in these categories wouldn't change the fact
+   that they match patterns reserved for the compiler, so the codegen does not
+   currently attempt to fix them. Such names will therefore result in
+   non-portable code that may or may not work depending on the compiler. These
+   naming patterns are of course strongly discouraged in any protobufs that will
+   be used with ``pw_protobuf`` codegen.
 
 Overhead
 ========
@@ -1215,27 +1214,27 @@
 The simplest way to use ``MemoryEncoder`` to encode a proto is from its code
 generated ``Message`` structure into an in-memory buffer.
 
-.. code:: c++
+.. code-block:: c++
 
-  #include "my_protos/my_proto.pwpb.h"
-  #include "pw_bytes/span.h"
-  #include "pw_protobuf/encoder.h"
-  #include "pw_status/status_with_size.h"
+   #include "my_protos/my_proto.pwpb.h"
+   #include "pw_bytes/span.h"
+   #include "pw_protobuf/encoder.h"
+   #include "pw_status/status_with_size.h"
 
-  // Writes a proto response to the provided buffer, returning the encode
-  // status and number of bytes written.
-  pw::StatusWithSize WriteProtoResponse(pw::ByteSpan response) {
-    MyProto::Message message{}
-    message.magic_number = 0x1a1a2b2b;
-    message.favorite_food = "cookies";
-    message.calories = 600;
+   // Writes a proto response to the provided buffer, returning the encode
+   // status and number of bytes written.
+   pw::StatusWithSize WriteProtoResponse(pw::ByteSpan response) {
+     MyProto::Message message{}
+     message.magic_number = 0x1a1a2b2b;
+     message.favorite_food = "cookies";
+     message.calories = 600;
 
-    // All proto writes are directly written to the `response` buffer.
-    MyProto::MemoryEncoder encoder(response);
-    encoder.Write(message);
+     // All proto writes are directly written to the `response` buffer.
+     MyProto::MemoryEncoder encoder(response);
+     encoder.Write(message);
 
-    return pw::StatusWithSize(encoder.status(), encoder.size());
-  }
+     return pw::StatusWithSize(encoder.status(), encoder.size());
+   }
 
 All fields of a message are written, including those initialized to their
 default values.
@@ -1245,52 +1244,52 @@
 or lower-level APIs. This can be more convenient if finer grained control or
 other custom handling is required.
 
-.. code:: c++
+.. code-block:: c++
 
-  #include "my_protos/my_proto.pwpb.h"
-  #include "pw_bytes/span.h"
-  #include "pw_protobuf/encoder.h"
-  #include "pw_status/status_with_size.h"
+   #include "my_protos/my_proto.pwpb.h"
+   #include "pw_bytes/span.h"
+   #include "pw_protobuf/encoder.h"
+   #include "pw_status/status_with_size.h"
 
-  // Writes a proto response to the provided buffer, returning the encode
-  // status and number of bytes written.
-  pw::StatusWithSize WriteProtoResponse(pw::ByteSpan response) {
-    // All proto writes are directly written to the `response` buffer.
-    MyProto::MemoryEncoder encoder(response);
-    encoder.WriteMagicNumber(0x1a1a2b2b);
-    encoder.WriteFavoriteFood("cookies");
-    // Only conditionally write calories.
-    if (on_diet) {
-      encoder.WriteCalories(600);
-    }
-    return pw::StatusWithSize(encoder.status(), encoder.size());
-  }
+   // Writes a proto response to the provided buffer, returning the encode
+   // status and number of bytes written.
+   pw::StatusWithSize WriteProtoResponse(pw::ByteSpan response) {
+     // All proto writes are directly written to the `response` buffer.
+     MyProto::MemoryEncoder encoder(response);
+     encoder.WriteMagicNumber(0x1a1a2b2b);
+     encoder.WriteFavoriteFood("cookies");
+     // Only conditionally write calories.
+     if (on_diet) {
+       encoder.WriteCalories(600);
+     }
+     return pw::StatusWithSize(encoder.status(), encoder.size());
+   }
 
 StreamEncoder
 =============
 ``StreamEncoder`` is constructed with the destination stream, and a scratch
 buffer used to handle nested submessages.
 
-.. code:: c++
+.. code-block:: c++
 
-  #include "my_protos/my_proto.pwpb.h"
-  #include "pw_bytes/span.h"
-  #include "pw_protobuf/encoder.h"
-  #include "pw_stream/sys_io_stream.h"
+   #include "my_protos/my_proto.pwpb.h"
+   #include "pw_bytes/span.h"
+   #include "pw_protobuf/encoder.h"
+   #include "pw_stream/sys_io_stream.h"
 
-  pw::stream::SysIoWriter sys_io_writer;
-  MyProto::StreamEncoder encoder(sys_io_writer, pw::ByteSpan());
+   pw::stream::SysIoWriter sys_io_writer;
+   MyProto::StreamEncoder encoder(sys_io_writer, pw::ByteSpan());
 
-  // Once this line returns, the field has been written to the Writer.
-  encoder.WriteTimestamp(system::GetUnixEpoch());
+   // Once this line returns, the field has been written to the Writer.
+   encoder.WriteTimestamp(system::GetUnixEpoch());
 
-  // There's no intermediate buffering when writing a string directly to a
-  // StreamEncoder.
-  encoder.WriteWelcomeMessage("Welcome to Pigweed!");
+   // There's no intermediate buffering when writing a string directly to a
+   // StreamEncoder.
+   encoder.WriteWelcomeMessage("Welcome to Pigweed!");
 
-  if (!encoder.status().ok()) {
-    PW_LOG_INFO("Failed to encode proto; %s", encoder.status().str());
-  }
+   if (!encoder.status().ok()) {
+     PW_LOG_INFO("Failed to encode proto; %s", encoder.status().str());
+   }
 
 Callbacks
 =========
@@ -1306,25 +1305,25 @@
 nested submessage (with a dependency cycle, or repeated) can be implemented by
 calling ``Write()`` on a nested encoder.
 
-.. code:: c++
+.. code-block:: c++
 
-    Store::Message store{};
-    store.employees.SetEncoder([](Store::StreamEncoder& encoder) {
-      Employee::Message employee{};
-      // Populate `employee`.
-      return encoder.GetEmployeesEncoder().Write(employee);
-    ));
+   Store::Message store{};
+   store.employees.SetEncoder([](Store::StreamEncoder& encoder) {
+     Employee::Message employee{};
+     // Populate `employee`.
+     return encoder.GetEmployeesEncoder().Write(employee);
+   ));
 
 Nested submessages
 ==================
 Code generated ``GetFieldEncoder`` methods are provided that return a correctly
 typed ``StreamEncoder`` or ``MemoryEncoder`` for the message.
 
-.. code::
+.. code-block:: protobuf
 
-  message Owner {
-    Animal pet = 1;
-  }
+   message Owner {
+     Animal pet = 1;
+   }
 
 Note that the accessor method is named for the field, while the returned encoder
 is named for the message type.
@@ -1341,9 +1340,9 @@
 that nested decoder.)
 
 .. warning::
-  When a nested submessage is created, any use of the parent encoder that
-  created the nested encoder will trigger a crash. To resume using the parent
-  encoder, destroy the submessage encoder first.
+   When a nested submessage is created, any use of the parent encoder that
+   created the nested encoder will trigger a crash. To resume using the parent
+   encoder, destroy the submessage encoder first.
 
 Buffering
 ---------
@@ -1370,40 +1369,40 @@
 also be useful in estimating how much space to allocate to account for nested
 submessage encoding overhead.
 
-.. code:: c++
+.. code-block:: c++
 
-  #include "my_protos/pets.pwpb.h"
-  #include "pw_bytes/span.h"
-  #include "pw_protobuf/encoder.h"
-  #include "pw_stream/sys_io_stream.h"
+   #include "my_protos/pets.pwpb.h"
+   #include "pw_bytes/span.h"
+   #include "pw_protobuf/encoder.h"
+   #include "pw_stream/sys_io_stream.h"
 
-  pw::stream::SysIoWriter sys_io_writer;
-  // The scratch buffer should be at least as big as the largest nested
-  // submessage. It's a good idea to be a little generous.
-  std::byte submessage_scratch_buffer[Owner::kScratchBufferSizeBytes];
+   pw::stream::SysIoWriter sys_io_writer;
+   // The scratch buffer should be at least as big as the largest nested
+   // submessage. It's a good idea to be a little generous.
+   std::byte submessage_scratch_buffer[Owner::kScratchBufferSizeBytes];
 
-  // Provide the scratch buffer to the proto encoder. The buffer's lifetime must
-  // match the lifetime of the encoder.
-  Owner::StreamEncoder owner_encoder(sys_io_writer, submessage_scratch_buffer);
+   // Provide the scratch buffer to the proto encoder. The buffer's lifetime must
+   // match the lifetime of the encoder.
+   Owner::StreamEncoder owner_encoder(sys_io_writer, submessage_scratch_buffer);
 
-  {
-    // Note that the parent encoder, owner_encoder, cannot be used until the
-    // nested encoder, pet_encoder, has been destroyed.
-    Animal::StreamEncoder pet_encoder = owner_encoder.GetPetEncoder();
+   {
+     // Note that the parent encoder, owner_encoder, cannot be used until the
+     // nested encoder, pet_encoder, has been destroyed.
+     Animal::StreamEncoder pet_encoder = owner_encoder.GetPetEncoder();
 
-    // There's intermediate buffering when writing to a nested encoder.
-    pet_encoder.WriteName("Spot");
-    pet_encoder.WriteType(Pet::Type::DOG);
+     // There's intermediate buffering when writing to a nested encoder.
+     pet_encoder.WriteName("Spot");
+     pet_encoder.WriteType(Pet::Type::DOG);
 
-    // When this scope ends, the nested encoder is serialized to the Writer.
-    // In addition, the parent encoder, owner_encoder, can be used again.
-  }
+     // When this scope ends, the nested encoder is serialized to the Writer.
+     // In addition, the parent encoder, owner_encoder, can be used again.
+   }
 
-  // If an encode error occurs when encoding the nested messages, it will be
-  // reflected at the root encoder.
-  if (!owner_encoder.status().ok()) {
-    PW_LOG_INFO("Failed to encode proto; %s", owner_encoder.status().str());
-  }
+   // If an encode error occurs when encoding the nested messages, it will be
+   // reflected at the root encoder.
+   if (!owner_encoder.status().ok()) {
+     PW_LOG_INFO("Failed to encode proto; %s", owner_encoder.status().str());
+   }
 
 MemoryEncoder objects use the final destination buffer rather than relying on a
 scratch buffer.  The ``kMaxEncodedSizeBytes`` constant takes into account the
@@ -1411,10 +1410,10 @@
 yourself, your destination buffer might need additional space.
 
 .. warning::
-  If the scratch buffer size is not sufficient, the encoding will fail with
-  ``Status::ResourceExhausted()``. Always check the results of ``Write`` calls
-  or the encoder status to ensure success, as otherwise the encoded data will
-  be invalid.
+   If the scratch buffer size is not sufficient, the encoding will fail with
+   ``Status::ResourceExhausted()``. Always check the results of ``Write`` calls
+   or the encoder status to ensure success, as otherwise the encoded data will
+   be invalid.
 
 Scalar Fields
 =============
@@ -1443,10 +1442,10 @@
 The following two method calls are equivalent, where the first is using the
 code generated API, and the second implemented by hand.
 
-.. code:: c++
+.. code-block:: c++
 
-  my_proto_encoder.WriteAge(42);
-  my_proto_encoder.WriteInt32(static_cast<uint32_t>(MyProto::Fields::kAge), 42);
+   my_proto_encoder.WriteAge(42);
+   my_proto_encoder.WriteInt32(static_cast<uint32_t>(MyProto::Fields::kAge), 42);
 
 Repeated Fields
 ---------------
@@ -1455,13 +1454,13 @@
 
 .. cpp:function:: Status MyProto::StreamEncoder::WriteFoos(T)
 
-  This writes a single unpacked value.
+   This writes a single unpacked value.
 
 .. cpp:function:: Status MyProto::StreamEncoder::WriteFoos(pw::span<const T>)
 .. cpp:function:: Status MyProto::StreamEncoder::WriteFoos(const pw::Vector<T>&)
 
-  These write a packed field containing all of the values in the provided span
-  or vector.
+   These write a packed field containing all of the values in the provided span
+   or vector.
 
 These too can be freely intermixed with the lower-level API methods, both to
 write a single value, or to write packed values from either a ``pw::span`` or
@@ -1493,14 +1492,14 @@
 The following two method calls are equivalent, where the first is using the
 code generated API, and the second implemented by hand.
 
-.. code:: c++
+.. code-block:: c++
 
-  constexpr std::array<int32_t, 5> numbers = { 4, 8, 15, 16, 23, 42 };
+   constexpr std::array<int32_t, 5> numbers = { 4, 8, 15, 16, 23, 42 };
 
-  my_proto_encoder.WriteNumbers(numbers);
-  my_proto_encoder.WritePackedInt32(
-      static_cast<uint32_t>(MyProto::Fields::kNumbers),
-      numbers);
+   my_proto_encoder.WriteNumbers(numbers);
+   my_proto_encoder.WritePackedInt32(
+       static_cast<uint32_t>(MyProto::Fields::kNumbers),
+       numbers);
 
 Enumerations
 ============
@@ -1516,12 +1515,12 @@
 The following two methods are equivalent, where the first is code generated,
 and the second implemented by hand.
 
-.. code:: c++
+.. code-block:: c++
 
-  my_proto_encoder.WriteAward(MyProto::Award::SILVER);
-  my_proto_encoder.WriteUint32(
-      static_cast<uint32_t>(MyProto::Fields::kAward),
-      static_cast<uint32_t>(MyProto::Award::SILVER));
+   my_proto_encoder.WriteAward(MyProto::Award::SILVER);
+   my_proto_encoder.WriteUint32(
+       static_cast<uint32_t>(MyProto::Fields::kAward),
+       static_cast<uint32_t>(MyProto::Award::SILVER));
 
 Repeated Fields
 ---------------
@@ -1530,13 +1529,13 @@
 
 .. cpp:function:: Status MyProto::StreamEncoder::WriteEnums(MyProto::Enums)
 
-  This writes a single unpacked value.
+   This writes a single unpacked value.
 
 .. cpp:function:: Status MyProto::StreamEncoder::WriteEnums(pw::span<const MyProto::Enums>)
 .. cpp:function:: Status MyProto::StreamEncoder::WriteEnums(const pw::Vector<MyProto::Enums>&)
 
-  These write a packed field containing all of the values in the provided span
-  or vector.
+   These write a packed field containing all of the values in the provided span
+   or vector.
 
 Their use is as scalar fields.
 
@@ -1557,9 +1556,9 @@
 
 .. cpp:function:: Status pw::protobuf::StreamEncoder::WriteStringFromStream(uint32_t field_number, stream::Reader& bytes_reader, size_t num_bytes, ByteSpan stream_pipe_buffer)
 
-  The payload for the value is provided through the stream::Reader
-  ``bytes_reader``. The method reads a chunk of the data from the reader using
-  the ``stream_pipe_buffer`` and writes it to the encoder.
+   The payload for the value is provided through the stream::Reader
+   ``bytes_reader``. The method reads a chunk of the data from the reader using
+   the ``stream_pipe_buffer`` and writes it to the encoder.
 
 Bytes
 =====
@@ -1575,9 +1574,9 @@
 
 .. cpp:function:: Status pw::protobuf::StreamEncoder::WriteBytesFromStream(uint32_t field_number, stream::Reader& bytes_reader, size_t num_bytes, ByteSpan stream_pipe_buffer)
 
-  The payload for the value is provided through the stream::Reader
-  ``bytes_reader``. The method reads a chunk of the data from the reader using
-  the ``stream_pipe_buffer`` and writes it to the encoder.
+   The payload for the value is provided through the stream::Reader
+   ``bytes_reader``. The method reads a chunk of the data from the reader using
+   the ``stream_pipe_buffer`` and writes it to the encoder.
 
 Error Handling
 ==============
@@ -1591,8 +1590,8 @@
 submessages (e.g. ``map<string, bytes>``) are provided in
 ``pw_protobuf/map_utils.h``.
 
-.. Note::
-  The helper API are currently in-development and may not remain stable.
+.. note::
+   The helper API are currently in-development and may not remain stable.
 
 --------
 Decoding
@@ -1600,19 +1599,19 @@
 The simplest way to use ``StreamDecoder`` is to decode a proto from the stream
 into its code generated ``Message`` structure.
 
-.. code:: c++
+.. code-block:: c++
 
-  #include "my_protos/my_proto.pwpb.h"
-  #include "pw_protobuf/stream_decoder.h"
-  #include "pw_status/status.h"
-  #include "pw_stream/stream.h"
+   #include "my_protos/my_proto.pwpb.h"
+   #include "pw_protobuf/stream_decoder.h"
+   #include "pw_status/status.h"
+   #include "pw_stream/stream.h"
 
-  pw::Status DecodeProtoFromStream(pw::stream::Reader& reader) {
-    MyProto::Message message{};
-    MyProto::StreamDecoder decoder(reader);
-    decoder.Read(message);
-    return decoder.status();
-  }
+   pw::Status DecodeProtoFromStream(pw::stream::Reader& reader) {
+     MyProto::Message message{};
+     MyProto::StreamDecoder decoder(reader);
+     decoder.Read(message);
+     return decoder.status();
+   }
 
 In the case of errors, the decoding will stop and return with the cursor on the
 field that caused the error. It is valid in some cases to inspect the error and
@@ -1634,47 +1633,47 @@
 .. cpp:function:: Result<MyProto::Fields> MyProto::StreamDecoder::Field()
 .. cpp:function:: Result<uint32_t> pw::protobuf::StreamDecoder::FieldNumber()
 
-.. code:: c++
+.. code-block:: c++
 
-  #include "my_protos/my_proto.pwpb.h"
-  #include "pw_protobuf/strema_decoder.h"
-  #include "pw_status/status.h"
-  #include "pw_status/try.h"
-  #include "pw_stream/stream.h"
+   #include "my_protos/my_proto.pwpb.h"
+   #include "pw_protobuf/strema_decoder.h"
+   #include "pw_status/status.h"
+   #include "pw_status/try.h"
+   #include "pw_stream/stream.h"
 
-  pw::Status DecodeProtoFromStream(pw::stream::Reader& reader) {
-    MyProto::StreamDecoder decoder(reader);
-    pw::Status status;
+   pw::Status DecodeProtoFromStream(pw::stream::Reader& reader) {
+     MyProto::StreamDecoder decoder(reader);
+     pw::Status status;
 
-    uint32_t age;
-    char name[16];
+     uint32_t age;
+     char name[16];
 
-    // Iterate over the fields in the message. A return value of OK indicates
-    // that a valid field has been found and can be read. When the decoder
-    // reaches the end of the message, Next() will return OUT_OF_RANGE.
-    // Other return values indicate an error trying to decode the message.
-    while ((status = decoder.Next()).ok()) {
-      // Field() returns a Result<Fields> as it may fail sometimes.
-      // However, Field() is guaranteed to be valid after a call to Next()
-      // that returns OK, so the value can be used directly here.
-      switch (decoder.Field().value()) {
-        case MyProto::Fields::kAge: {
-          PW_TRY_ASSIGN(age, decoder.ReadAge());
-          break;
-        }
-        case MyProto::Fields::kName:
-          // The string field is copied into the provided buffer. If the buffer
-          // is too small to fit the string, RESOURCE_EXHAUSTED is returned and
-          // the decoder is not advanced, allowing the field to be re-read.
-          PW_TRY(decoder.ReadName(name));
-          break;
-      }
-    }
+     // Iterate over the fields in the message. A return value of OK indicates
+     // that a valid field has been found and can be read. When the decoder
+     // reaches the end of the message, Next() will return OUT_OF_RANGE.
+     // Other return values indicate an error trying to decode the message.
+     while ((status = decoder.Next()).ok()) {
+       // Field() returns a Result<Fields> as it may fail sometimes.
+       // However, Field() is guaranteed to be valid after a call to Next()
+       // that returns OK, so the value can be used directly here.
+       switch (decoder.Field().value()) {
+         case MyProto::Fields::kAge: {
+           PW_TRY_ASSIGN(age, decoder.ReadAge());
+           break;
+         }
+         case MyProto::Fields::kName:
+           // The string field is copied into the provided buffer. If the buffer
+           // is too small to fit the string, RESOURCE_EXHAUSTED is returned and
+           // the decoder is not advanced, allowing the field to be re-read.
+           PW_TRY(decoder.ReadName(name));
+           break;
+       }
+     }
 
-    // Do something with the fields...
+     // Do something with the fields...
 
-    return status.IsOutOfRange() ? OkStatus() : status;
-  }
+     return status.IsOutOfRange() ? OkStatus() : status;
+   }
 
 Callbacks
 =========
@@ -1690,29 +1689,29 @@
 nested submessage (with a dependency cycle, or repeated) can be implemented by
 calling ``Read()`` on a nested decoder.
 
-.. code:: c++
+.. code-block:: c++
 
-    Store::Message store{};
-    store.employees.SetDecoder([](Store::StreamDecoder& decoder) {
-      PW_ASSERT(decoder.Field().value() == Store::Fields::kEmployees);
+   Store::Message store{};
+   store.employees.SetDecoder([](Store::StreamDecoder& decoder) {
+     PW_ASSERT(decoder.Field().value() == Store::Fields::kEmployees);
 
-      Employee::Message employee{};
-      // Set any callbacks on `employee`.
-      PW_TRY(decoder.GetEmployeesDecoder().Read(employee));
-      // Do things with `employee`.
-      return OkStatus();
-    ));
+     Employee::Message employee{};
+     // Set any callbacks on `employee`.
+     PW_TRY(decoder.GetEmployeesDecoder().Read(employee));
+     // Do things with `employee`.
+     return OkStatus();
+   ));
 
 Nested submessages
 ==================
 Code generated ``GetFieldDecoder`` methods are provided that return a correctly
 typed ``StreamDecoder`` for the message.
 
-.. code::
+.. code-block:: protobuf
 
-  message Owner {
-    Animal pet = 1;
-  }
+   message Owner {
+     Animal pet = 1;
+   }
 
 As with encoding, note that the accessor method is named for the field, while
 the returned decoder is named for the message type.
@@ -1725,28 +1724,28 @@
 .. cpp:function:: pw::protobuf::StreamDecoder pw::protobuf::StreamDecoder::GetNestedDecoder()
 
 .. warning::
-  When a nested submessage is being decoded, any use of the parent decoder that
-  created the nested decoder will trigger a crash. To resume using the parent
-  decoder, destroy the submessage decoder first.
+   When a nested submessage is being decoded, any use of the parent decoder that
+   created the nested decoder will trigger a crash. To resume using the parent
+   decoder, destroy the submessage decoder first.
 
 
-.. code:: c++
+.. code-block:: c++
 
-  case Owner::Fields::kPet: {
-    // Note that the parent decoder, owner_decoder, cannot be used until the
-    // nested decoder, pet_decoder, has been destroyed.
-    Animal::StreamDecoder pet_decoder = owner_decoder.GetPetDecoder();
+   case Owner::Fields::kPet: {
+     // Note that the parent decoder, owner_decoder, cannot be used until the
+     // nested decoder, pet_decoder, has been destroyed.
+     Animal::StreamDecoder pet_decoder = owner_decoder.GetPetDecoder();
 
-    while ((status = pet_decoder.Next()).ok()) {
-      switch (pet_decoder.Field().value()) {
-        // Decode pet fields...
-      }
-    }
+     while ((status = pet_decoder.Next()).ok()) {
+       switch (pet_decoder.Field().value()) {
+         // Decode pet fields...
+       }
+     }
 
-    // When this scope ends, the nested decoder is destroyed and the
-    // parent decoder, owner_decoder, can be used again.
-    break;
-  }
+     // When this scope ends, the nested decoder is destroyed and the
+     // parent decoder, owner_decoder, can be used again.
+     break;
+   }
 
 Scalar Fields
 =============
@@ -1773,15 +1772,15 @@
 The following two code snippets are equivalent, where the first uses the code
 generated API, and the second implemented by hand.
 
-.. code:: c++
+.. code-block:: c++
 
-  pw::Result<int32_t> age = my_proto_decoder.ReadAge();
+   pw::Result<int32_t> age = my_proto_decoder.ReadAge();
 
-.. code:: c++
+.. code-block:: c++
 
-  PW_ASSERT(my_proto_decoder.FieldNumber().value() ==
-      static_cast<uint32_t>(MyProto::Fields::kAge));
-  pw::Result<int32_t> my_proto_decoder.ReadInt32();
+   PW_ASSERT(my_proto_decoder.FieldNumber().value() ==
+       static_cast<uint32_t>(MyProto::Fields::kAge));
+   pw::Result<int32_t> my_proto_decoder.ReadInt32();
 
 Repeated Fields
 ---------------
@@ -1790,20 +1789,20 @@
 
 .. cpp:function:: Result<T> MyProto::StreamDecoder::ReadFoos()
 
-  This reads a single unpacked value.
+   This reads a single unpacked value.
 
 .. cpp:function:: StatusWithSize MyProto::StreamDecoder::ReadFoos(pw::span<T>)
 
-  This reads a packed field containing all of the values into the provided span.
+   This reads a packed field containing all of the values into the provided span.
 
 .. cpp:function:: Status MyProto::StreamDecoder::ReadFoos(pw::Vector<T>&)
 
-  Protobuf encoders are permitted to choose either repeating single unpacked
-  values, or a packed field, including splitting repeated fields up into
-  multiple packed fields.
+   Protobuf encoders are permitted to choose either repeating single unpacked
+   values, or a packed field, including splitting repeated fields up into
+   multiple packed fields.
 
-  This method supports either format, appending values to the provided
-  ``pw::Vector``.
+   This method supports either format, appending values to the provided
+   ``pw::Vector``.
 
 These too can be freely intermixed with the lower-level API methods, to read a
 single value, a field of packed values into a ``pw::span``, or support both
@@ -1835,19 +1834,19 @@
 The following two code blocks are equivalent, where the first uses the code
 generated API, and the second is implemented by hand.
 
-.. code:: c++
+.. code-block:: c++
 
-  pw::Vector<int32_t, 8> numbers;
+   pw::Vector<int32_t, 8> numbers;
 
-  my_proto_decoder.ReadNumbers(numbers);
+   my_proto_decoder.ReadNumbers(numbers);
 
-.. code:: c++
+.. code-block:: c++
 
-  pw::Vector<int32_t, 8> numbers;
+   pw::Vector<int32_t, 8> numbers;
 
-  PW_ASSERT(my_proto_decoder.FieldNumber().value() ==
-      static_cast<uint32_t>(MyProto::Fields::kNumbers));
-  my_proto_decoder.ReadRepeatedInt32(numbers);
+   PW_ASSERT(my_proto_decoder.FieldNumber().value() ==
+       static_cast<uint32_t>(MyProto::Fields::kNumbers));
+   my_proto_decoder.ReadRepeatedInt32(numbers);
 
 Enumerations
 ============
@@ -1861,14 +1860,14 @@
 
 .. cpp:function:: constexpr bool MyProto::IsValidEnum(MyProto::Enum value)
 
-  Validates the value encoded in the wire format against the known set of
-  enumerates.
+   Validates the value encoded in the wire format against the known set of
+   enumerates.
 
 .. cpp:function:: constexpr const char* MyProto::EnumToString(MyProto::Enum value)
 
-  Returns the string representation of the enum value. For example,
-  ``FooToString(Foo::kBarBaz)`` returns ``"BAR_BAZ"``. Returns the empty string
-  if the value is not a valid value.
+   Returns the string representation of the enum value. For example,
+   ``FooToString(Foo::kBarBaz)`` returns ``"BAR_BAZ"``. Returns the empty string
+   if the value is not a valid value.
 
 To read enumerations with the lower-level API, you would need to cast the
 retured value from the ``uint32_t``.
@@ -1878,19 +1877,19 @@
 
 .. code-block:: c++
 
-  pw::Result<MyProto::Award> award = my_proto_decoder.ReadAward();
-  if (!MyProto::IsValidAward(award)) {
-    PW_LOG_DBG("Unknown award");
-  }
+   pw::Result<MyProto::Award> award = my_proto_decoder.ReadAward();
+   if (!MyProto::IsValidAward(award)) {
+     PW_LOG_DBG("Unknown award");
+   }
 
 .. code-block:: c++
 
-  PW_ASSERT(my_proto_decoder.FieldNumber().value() ==
-      static_cast<uint32_t>(MyProto::Fields::kAward));
-  pw::Result<uint32_t> award_value = my_proto_decoder.ReadUint32();
-  if (award_value.ok()) {
-    MyProto::Award award = static_cast<MyProto::Award>(award_value);
-  }
+   PW_ASSERT(my_proto_decoder.FieldNumber().value() ==
+       static_cast<uint32_t>(MyProto::Fields::kAward));
+   pw::Result<uint32_t> award_value = my_proto_decoder.ReadUint32();
+   if (award_value.ok()) {
+     MyProto::Award award = static_cast<MyProto::Award>(award_value);
+   }
 
 Repeated Fields
 ---------------
@@ -1899,17 +1898,17 @@
 
 .. cpp:function:: Result<MyProto::Enums> MyProto::StreamDecoder::ReadEnums()
 
-  This reads a single unpacked value.
+   This reads a single unpacked value.
 
 .. cpp:function:: StatusWithSize MyProto::StreamDecoder::ReadEnums(pw::span<MyProto::Enums>)
 
-  This reads a packed field containing all of the checked values into the
-  provided span.
+   This reads a packed field containing all of the checked values into the
+   provided span.
 
 .. cpp:function:: Status MyProto::StreamDecoder::ReadEnums(pw::Vector<MyProto::Enums>&)
 
-  This method supports either repeated unpacked or packed formats, appending
-  checked values to the provided ``pw::Vector``.
+   This method supports either repeated unpacked or packed formats, appending
+   checked values to the provided ``pw::Vector``.
 
 Their use is as scalar fields.
 
@@ -1973,9 +1972,9 @@
 be prevented from reading from the stream beyond the known bounds by specifying
 the known length to the decoder:
 
-.. code:: c++
+.. code-block:: c++
 
-  pw::protobuf::StreamDecoder decoder(reader, message_length);
+   pw::protobuf::StreamDecoder decoder(reader, message_length);
 
 When a decoder constructed in this way goes out of scope, it will consume any
 remaining bytes in ``message_length`` allowing the next ``Read()`` on the stream
@@ -1998,39 +1997,39 @@
 When reading ``bytes`` and ``string`` fields, the decoder returns a view of that
 field within the buffer; no data is copied out.
 
-.. code:: c++
+.. code-block:: c++
 
-  #include "pw_protobuf/decoder.h"
-  #include "pw_status/try.h"
+   #include "pw_protobuf/decoder.h"
+   #include "pw_status/try.h"
 
-  pw::Status DecodeProtoFromBuffer(pw::span<const std::byte> buffer) {
-    pw::protobuf::Decoder decoder(buffer);
-    pw::Status status;
+   pw::Status DecodeProtoFromBuffer(pw::span<const std::byte> buffer) {
+     pw::protobuf::Decoder decoder(buffer);
+     pw::Status status;
 
-    uint32_t uint32_field;
-    std::string_view string_field;
+     uint32_t uint32_field;
+     std::string_view string_field;
 
-    // Iterate over the fields in the message. A return value of OK indicates
-    // that a valid field has been found and can be read. When the decoder
-    // reaches the end of the message, Next() will return OUT_OF_RANGE.
-    // Other return values indicate an error trying to decode the message.
-    while ((status = decoder.Next()).ok()) {
-      switch (decoder.FieldNumber()) {
-        case 1:
-          PW_TRY(decoder.ReadUint32(&uint32_field));
-          break;
-        case 2:
-          // The passed-in string_view will point to the contents of the string
-          // field within the buffer.
-          PW_TRY(decoder.ReadString(&string_field));
-          break;
-      }
-    }
+     // Iterate over the fields in the message. A return value of OK indicates
+     // that a valid field has been found and can be read. When the decoder
+     // reaches the end of the message, Next() will return OUT_OF_RANGE.
+     // Other return values indicate an error trying to decode the message.
+     while ((status = decoder.Next()).ok()) {
+       switch (decoder.FieldNumber()) {
+         case 1:
+           PW_TRY(decoder.ReadUint32(&uint32_field));
+           break;
+         case 2:
+           // The passed-in string_view will point to the contents of the string
+           // field within the buffer.
+           PW_TRY(decoder.ReadString(&string_field));
+           break;
+       }
+     }
 
-    // Do something with the fields...
+     // Do something with the fields...
 
-    return status.IsOutOfRange() ? OkStatus() : status;
-  }
+     return status.IsOutOfRange() ? OkStatus() : status;
+   }
 
 ---------------
 Message Decoder
@@ -2038,8 +2037,8 @@
 
 .. note::
 
-  ``pw::protobuf::Message`` is unrelated to the codegen ``struct Message``
-  used with ``StreamDecoder``.
+   ``pw::protobuf::Message`` is unrelated to the codegen ``struct Message``
+   used with ``StreamDecoder``.
 
 The module implements a message parsing helper class ``Message``, in
 ``pw_protobuf/message.h``, to faciliate proto message parsing and field access.
@@ -2050,120 +2049,120 @@
 message access. The following gives examples for using the class to process
 different fields in a proto message:
 
-.. code:: c++
+.. code-block:: c++
 
-  // Consider the proto messages defined as follows:
-  //
-  // message Nested {
-  //   string nested_str = 1;
-  //   bytes nested_bytes = 2;
-  // }
-  //
-  // message {
-  //   uint32 integer = 1;
-  //   string str = 2;
-  //   bytes bytes = 3;
-  //   Nested nested = 4;
-  //   repeated string rep_str = 5;
-  //   repeated Nested rep_nested  = 6;
-  //   map<string, bytes> str_to_bytes = 7;
-  //   map<string, Nested> str_to_nested = 8;
-  // }
+   // Consider the proto messages defined as follows:
+   //
+   // message Nested {
+   //   string nested_str = 1;
+   //   bytes nested_bytes = 2;
+   // }
+   //
+   // message {
+   //   uint32 integer = 1;
+   //   string str = 2;
+   //   bytes bytes = 3;
+   //   Nested nested = 4;
+   //   repeated string rep_str = 5;
+   //   repeated Nested rep_nested  = 6;
+   //   map<string, bytes> str_to_bytes = 7;
+   //   map<string, Nested> str_to_nested = 8;
+   // }
 
-  // Given a seekable `reader` that reads the top-level proto message, and
-  // a <proto_size> that gives the size of the proto message:
-  Message message(reader, proto_size);
+   // Given a seekable `reader` that reads the top-level proto message, and
+   // a <proto_size> that gives the size of the proto message:
+   Message message(reader, proto_size);
 
-  // Parse a proto integer field
-  Uint32 integer = messasge_parser.AsUint32(1);
-  if (!integer.ok()) {
-    // handle parsing error. i.e. return integer.status().
-  }
-  uint32_t integer_value = integer.value(); // obtained the value
+   // Parse a proto integer field
+   Uint32 integer = messasge_parser.AsUint32(1);
+   if (!integer.ok()) {
+     // handle parsing error. i.e. return integer.status().
+   }
+   uint32_t integer_value = integer.value(); // obtained the value
 
-  // Parse a string field
-  String str = message.AsString(2);
-  if (!str.ok()) {
-    // handle parsing error. i.e. return str.status();
-  }
+   // Parse a string field
+   String str = message.AsString(2);
+   if (!str.ok()) {
+     // handle parsing error. i.e. return str.status();
+   }
 
-  // check string equal
-  Result<bool> str_check = str.Equal("foo");
+   // check string equal
+   Result<bool> str_check = str.Equal("foo");
 
-  // Parse a bytes field
-  Bytes bytes = message.AsBytes(3);
-  if (!bytes.ok()) {
-    // handle parsing error. i.e. return bytes.status();
-  }
+   // Parse a bytes field
+   Bytes bytes = message.AsBytes(3);
+   if (!bytes.ok()) {
+     // handle parsing error. i.e. return bytes.status();
+   }
 
-  // Get a reader to the bytes.
-  stream::IntervalReader bytes_reader = bytes.GetBytesReader();
+   // Get a reader to the bytes.
+   stream::IntervalReader bytes_reader = bytes.GetBytesReader();
 
-  // Parse nested message `Nested nested = 4;`
-  Message nested = message.AsMessage(4).
-  // Get the fields in the nested message.
-  String nested_str = nested.AsString(1);
-  Bytes nested_bytes = nested.AsBytes(2);
+   // Parse nested message `Nested nested = 4;`
+   Message nested = message.AsMessage(4).
+   // Get the fields in the nested message.
+   String nested_str = nested.AsString(1);
+   Bytes nested_bytes = nested.AsBytes(2);
 
-  // Parse repeated field `repeated string rep_str = 5;`
-  RepeatedStrings rep_str = message.AsRepeatedString(5);
-  // Iterate through the entries. If proto is malformed when
-  // iterating, the next element (`str` in this case) will be invalid
-  // and loop will end in the iteration after.
-  for (String element : rep_str) {
-    // Check status
-    if (!str.ok()) {
-      // In the case of error, loop will end in the next iteration if
-      // continues. This is the chance for code to catch the error.
-    }
-    // Process str
-  }
+   // Parse repeated field `repeated string rep_str = 5;`
+   RepeatedStrings rep_str = message.AsRepeatedString(5);
+   // Iterate through the entries. If proto is malformed when
+   // iterating, the next element (`str` in this case) will be invalid
+   // and loop will end in the iteration after.
+   for (String element : rep_str) {
+     // Check status
+     if (!str.ok()) {
+       // In the case of error, loop will end in the next iteration if
+       // continues. This is the chance for code to catch the error.
+     }
+     // Process str
+   }
 
-  // Parse repeated field `repeated Nested rep_nested = 6;`
-  RepeatedStrings rep_str = message.AsRepeatedString(6);
-  // Iterate through the entries. For iteration
-  for (Message element : rep_rep_nestedstr) {
-    // Check status
-    if (!element.ok()) {
-      // In the case of error, loop will end in the next iteration if
-      // continues. This is the chance for code to catch the error.
-    }
-    // Process element
-  }
+   // Parse repeated field `repeated Nested rep_nested = 6;`
+   RepeatedStrings rep_str = message.AsRepeatedString(6);
+   // Iterate through the entries. For iteration
+   for (Message element : rep_rep_nestedstr) {
+     // Check status
+     if (!element.ok()) {
+       // In the case of error, loop will end in the next iteration if
+       // continues. This is the chance for code to catch the error.
+     }
+     // Process element
+   }
 
-  // Parse map field `map<string, bytes> str_to_bytes = 7;`
-  StringToBytesMap str_to_bytes = message.AsStringToBytesMap(7);
-  // Access the entry by a given key value
-  Bytes bytes_for_key = str_to_bytes["key"];
-  // Or iterate through map entries
-  for (StringToBytesMapEntry entry : str_to_bytes) {
-    // Check status
-    if (!entry.ok()) {
-      // In the case of error, loop will end in the next iteration if
-      // continues. This is the chance for code to catch the error.
-    }
-    String key = entry.Key();
-    Bytes value = entry.Value();
-    // process entry
-  }
+   // Parse map field `map<string, bytes> str_to_bytes = 7;`
+   StringToBytesMap str_to_bytes = message.AsStringToBytesMap(7);
+   // Access the entry by a given key value
+   Bytes bytes_for_key = str_to_bytes["key"];
+   // Or iterate through map entries
+   for (StringToBytesMapEntry entry : str_to_bytes) {
+     // Check status
+     if (!entry.ok()) {
+       // In the case of error, loop will end in the next iteration if
+       // continues. This is the chance for code to catch the error.
+     }
+     String key = entry.Key();
+     Bytes value = entry.Value();
+     // process entry
+   }
 
-  // Parse map field `map<string, Nested> str_to_nested = 8;`
-  StringToMessageMap str_to_nested = message.AsStringToBytesMap(8);
-  // Access the entry by a given key value
-  Message nested_for_key = str_to_nested["key"];
-  // Or iterate through map entries
-  for (StringToMessageMapEntry entry : str_to_nested) {
-    // Check status
-    if (!entry.ok()) {
-      // In the case of error, loop will end in the next iteration if
-      // continues. This is the chance for code to catch the error.
-      // However it is still recommended that the user breaks here.
-      break;
-    }
-    String key = entry.Key();
-    Message value = entry.Value();
-    // process entry
-  }
+   // Parse map field `map<string, Nested> str_to_nested = 8;`
+   StringToMessageMap str_to_nested = message.AsStringToBytesMap(8);
+   // Access the entry by a given key value
+   Message nested_for_key = str_to_nested["key"];
+   // Or iterate through map entries
+   for (StringToMessageMapEntry entry : str_to_nested) {
+     // Check status
+     if (!entry.ok()) {
+       // In the case of error, loop will end in the next iteration if
+       // continues. This is the chance for code to catch the error.
+       // However it is still recommended that the user breaks here.
+       break;
+     }
+     String key = entry.Key();
+     Message value = entry.Value();
+     // process entry
+   }
 
 The methods in ``Message`` for parsing a single field, i.e. everty `AsXXX()`
 method except AsRepeatedXXX() and AsStringMapXXX(), internally performs a
@@ -2175,28 +2174,28 @@
 single fields directly.
 
 
-.. code:: c++
+.. code-block:: c++
 
-  for (Message::Field field : message) {
-    // Check status
-    if (!field.ok()) {
-      // In the case of error, loop will end in the next iteration if
-      // continues. This is the chance for code to catch the error.
-    }
-    if (field.field_number() == 1) {
-      Uint32 integer = field.As<Uint32>();
-      ...
-    } else if (field.field_number() == 2) {
-      String str = field.As<String>();
-      ...
-    } else if (field.field_number() == 3) {
-      Bytes bytes = field.As<Bytes>();
-      ...
-    } else if (field.field_number() == 4) {
-      Message nested = field.As<Message>();
-      ...
-    }
-  }
+   for (Message::Field field : message) {
+     // Check status
+     if (!field.ok()) {
+       // In the case of error, loop will end in the next iteration if
+       // continues. This is the chance for code to catch the error.
+     }
+     if (field.field_number() == 1) {
+       Uint32 integer = field.As<Uint32>();
+       ...
+     } else if (field.field_number() == 2) {
+       String str = field.As<String>();
+       ...
+     } else if (field.field_number() == 3) {
+       Bytes bytes = field.As<Bytes>();
+       ...
+     } else if (field.field_number() == 4) {
+       Message nested = field.As<Message>();
+       ...
+     }
+   }
 
 
 .. Note::
@@ -2255,17 +2254,17 @@
 ============
 Contains the enum for pw::Status.
 
-.. Note::
- ``pw::protobuf::StatusCode`` values should not be used outside of a .proto
- file. Instead, the StatusCodes should be converted to the Status type in the
- language. In C++, this would be:
+.. note::
+   ``pw::protobuf::StatusCode`` values should not be used outside of a .proto
+   file. Instead, the StatusCodes should be converted to the Status type in the
+   language. In C++, this would be:
 
-  .. code:: c++
+   .. code-block:: c++
 
-    // Reading from a proto
-    pw::Status status = static_cast<pw::Status::Code>(proto.status_field));
-    // Writing to a proto
-    proto.status_field = static_cast<pw::protobuf::StatusCode>(status.code()));
+      // Reading from a proto
+      pw::Status status = static_cast<pw::Status::Code>(proto.status_field));
+      // Writing to a proto
+      proto.status_field = static_cast<pw::protobuf::StatusCode>(status.code()));
 
 ----------------------------------------
 Comparison with other protobuf libraries
diff --git a/pw_protobuf_compiler/docs.rst b/pw_protobuf_compiler/docs.rst
index dda5be1..3a446f0 100644
--- a/pw_protobuf_compiler/docs.rst
+++ b/pw_protobuf_compiler/docs.rst
@@ -55,9 +55,9 @@
 
 .. code-block::
 
-  pw_proto_library("test_protos") {
-    sources = [ "my_test_protos/test.proto" ]
-  }
+   pw_proto_library("test_protos") {
+     sources = [ "my_test_protos/test.proto" ]
+   }
 
 ``test_protos.pwpb`` compiles code for pw_protobuf, and ``test_protos.nanopb``
 compiles using Nanopb (if it's installed).
@@ -72,15 +72,15 @@
 
 .. code-block::
 
-  //path/to/my_protos:my_protos.pwpb
-  //path/to/my_protos:pwpb
+   //path/to/my_protos:my_protos.pwpb
+   //path/to/my_protos:pwpb
 
 ``pw_python_package`` subtargets are also available on the ``python`` subtarget:
 
 .. code-block::
 
-  //path/to/my_protos:my_protos.python.lint
-  //path/to/my_protos:python.lint
+   //path/to/my_protos:my_protos.python.lint
+   //path/to/my_protos:python.lint
 
 **Supported Codegen**
 
@@ -124,50 +124,50 @@
 
 .. code-block::
 
-  import("$dir_pw_protobuf_compiler/proto.gni")
+   import("$dir_pw_protobuf_compiler/proto.gni")
 
-  pw_proto_library("my_protos") {
-    sources = [
-      "my_protos/foo.proto",
-      "my_protos/bar.proto",
-    ]
-  }
+   pw_proto_library("my_protos") {
+     sources = [
+       "my_protos/foo.proto",
+       "my_protos/bar.proto",
+     ]
+   }
 
-  pw_proto_library("my_other_protos") {
-    sources = [ "some/other/path/baz.proto" ]  # imports foo.proto
+   pw_proto_library("my_other_protos") {
+     sources = [ "some/other/path/baz.proto" ]  # imports foo.proto
 
-    # This removes the "some/other/path" prefix from the proto files.
-    strip_prefix = "some/other/path"
+     # This removes the "some/other/path" prefix from the proto files.
+     strip_prefix = "some/other/path"
 
-    # This adds the "my_other_protos/" prefix to the proto files.
-    prefix = "my_other_protos"
+     # This adds the "my_other_protos/" prefix to the proto files.
+     prefix = "my_other_protos"
 
-    # Proto libraries depend on other proto libraries directly.
-    deps = [ ":my_protos" ]
-  }
+     # Proto libraries depend on other proto libraries directly.
+     deps = [ ":my_protos" ]
+   }
 
-  source_set("my_cc_code") {
-    sources = [
-      "foo.cc",
-      "bar.cc",
-      "baz.cc",
-    ]
+   source_set("my_cc_code") {
+     sources = [
+       "foo.cc",
+       "bar.cc",
+       "baz.cc",
+     ]
 
-    # When depending on protos in a source_set, specify the generator suffix.
-    deps = [ ":my_other_protos.pwpb" ]
-  }
+     # When depending on protos in a source_set, specify the generator suffix.
+     deps = [ ":my_other_protos.pwpb" ]
+   }
 
 From C++, ``baz.proto`` included as follows:
 
 .. code-block:: cpp
 
-  #include "my_other_protos/baz.pwpb.h"
+   #include "my_other_protos/baz.pwpb.h"
 
 From Python, ``baz.proto`` is imported as follows:
 
 .. code-block:: python
 
-  from my_other_protos import baz_pb2
+   from my_other_protos import baz_pb2
 
 Proto file structure
 --------------------
@@ -180,25 +180,25 @@
 
 .. code-block::
 
-  pw_proto_library("external_protos") {
-    sources = [
-      "//other/external/some_library/src/protos/alpha.proto",
-      "//other/external/some_library/src/protos/beta.proto,
-      "//other/external/some_library/src/protos/internal/gamma.proto",
-    ]
-    strip_prefix = "//other/external/some_library/src/protos"
-    prefix = "some_library"
-  }
+   pw_proto_library("external_protos") {
+     sources = [
+       "//other/external/some_library/src/protos/alpha.proto",
+       "//other/external/some_library/src/protos/beta.proto,
+       "//other/external/some_library/src/protos/internal/gamma.proto",
+     ]
+     strip_prefix = "//other/external/some_library/src/protos"
+     prefix = "some_library"
+   }
 
 These protos will be compiled by protoc as if they were in this file structure:
 
 .. code-block::
 
-  some_library/
-  ├── alpha.proto
-  ├── beta.proto
-  └── internal
-      └── gamma.proto
+   some_library/
+   ├── alpha.proto
+   ├── beta.proto
+   └── internal
+       └── gamma.proto
 
 .. _module-pw_protobuf_compiler-add-to-python-package:
 
@@ -215,30 +215,30 @@
 
 .. code-block::
 
-  pw_proto_library("my_protos") {
-    sources = [ "hello.proto ]
-    prefix = "foo"
-    python_package = ":my_package"
-  }
+   pw_proto_library("my_protos") {
+     sources = [ "hello.proto ]
+     prefix = "foo"
+     python_package = ":my_package"
+   }
 
-  pw_python_pacakge("my_package") {
-    generate_setup = {
-      metadata = {
-        name = "foo"
-        version = "1.0"
-      }
-    }
+   pw_python_pacakge("my_package") {
+     generate_setup = {
+       metadata = {
+         name = "foo"
+         version = "1.0"
+       }
+     }
 
-    sources = [ "foo/cool_module.py" ]
-    proto_library = ":my_protos"
-  }
+     sources = [ "foo/cool_module.py" ]
+     proto_library = ":my_protos"
+   }
 
 The ``hello_pb2.py`` proto module can be used alongside other files in the
 ``foo`` package.
 
 .. code-block:: python
 
-  from foo import cool_module, hello_pb2
+   from foo import cool_module, hello_pb2
 
 Working with externally defined protos
 --------------------------------------
@@ -256,11 +256,11 @@
 
 .. code-block::
 
-  pw_proto_library("proto") {
-    strip_prefix = "$dir_pw_third_party_nanopb/generator/proto"
-    sources = [ "$dir_pw_third_party_nanopb/generator/proto/nanopb.proto" ]
-    python_module_as_package = "nanopb_pb2"
-  }
+   pw_proto_library("proto") {
+     strip_prefix = "$dir_pw_third_party_nanopb/generator/proto"
+     sources = [ "$dir_pw_third_party_nanopb/generator/proto/nanopb.proto" ]
+     python_module_as_package = "nanopb_pb2"
+   }
 
 In Python, this makes ``nanopb.proto`` available as ``import nanopb_pb2`` via
 the ``nanopb_pb2`` Python package. In C++, ``nanopb.proto`` is accessed as
@@ -299,56 +299,56 @@
 
 **Example**
 
- .. code-block:: cmake
+.. code-block:: cmake
 
-  include($ENV{PW_ROOT}/pw_build/pigweed.cmake)
-  include($ENV{PW_ROOT}/pw_protobuf_compiler/proto.cmake)
+   include($ENV{PW_ROOT}/pw_build/pigweed.cmake)
+   include($ENV{PW_ROOT}/pw_protobuf_compiler/proto.cmake)
 
-  pw_proto_library(my_module.my_protos
-    SOURCES
-      my_protos/foo.proto
-      my_protos/bar.proto
-  )
+   pw_proto_library(my_module.my_protos
+     SOURCES
+       my_protos/foo.proto
+       my_protos/bar.proto
+   )
 
-  pw_proto_library(my_module.my_protos
-    SOURCES
-      my_protos/foo.proto
-      my_protos/bar.proto
-  )
+   pw_proto_library(my_module.my_protos
+     SOURCES
+       my_protos/foo.proto
+       my_protos/bar.proto
+   )
 
-  pw_proto_library(my_module.my_other_protos
-    SOURCES
-      some/other/path/baz.proto  # imports foo.proto
+   pw_proto_library(my_module.my_other_protos
+     SOURCES
+       some/other/path/baz.proto  # imports foo.proto
 
-    # This removes the "some/other/path" prefix from the proto files.
-    STRIP_PREFIX
-      some/other/path
+     # This removes the "some/other/path" prefix from the proto files.
+     STRIP_PREFIX
+       some/other/path
 
-    # This adds the "my_other_protos/" prefix to the proto files.
-    PREFIX
-      my_other_protos
+     # This adds the "my_other_protos/" prefix to the proto files.
+     PREFIX
+       my_other_protos
 
-    # Proto libraries depend on other proto libraries directly.
-    DEPS
-      my_module.my_protos
-  )
+     # Proto libraries depend on other proto libraries directly.
+     DEPS
+       my_module.my_protos
+   )
 
-  add_library(my_module.my_cc_code
-      foo.cc
-      bar.cc
-      baz.cc
-  )
+   add_library(my_module.my_cc_code
+       foo.cc
+       bar.cc
+       baz.cc
+   )
 
-  # When depending on protos in a source_set, specify the generator suffix.
-  target_link_libraries(my_module.my_cc_code PUBLIC
-    my_module.my_other_protos.pwpb
-  )
+   # When depending on protos in a source_set, specify the generator suffix.
+   target_link_libraries(my_module.my_cc_code PUBLIC
+     my_module.my_other_protos.pwpb
+   )
 
 These proto files are accessed in C++ the same as in the GN build:
 
 .. code-block:: cpp
 
-  #include "my_other_protos/baz.pwpb.h"
+   #include "my_other_protos/baz.pwpb.h"
 
 **Supported Codegen**
 
@@ -380,97 +380,96 @@
 
 .. code-block:: python
 
-  # WORKSPACE ...
-  load("@pigweed//pw_protobuf_compiler:deps.bzl", "pw_protobuf_dependencies")
-  pw_protobuf_dependencies()
+   # WORKSPACE ...
+   load("@pigweed//pw_protobuf_compiler:deps.bzl", "pw_protobuf_dependencies")
+   pw_protobuf_dependencies()
 
 Bazel uses a different set of rules to manage proto files than it does to
 compile them. e.g.
 
 .. code-block:: python
 
-  # BUILD ...
-  load("@rules_proto//proto:defs.bzl", "proto_library")
-  load("@pigweed//pw_protobuf_compiler:pw_proto_library.bzl",
-    "nanopb_proto_library",
-    "nanopb_rpc_proto_library",
-    "pwpb_proto_library",
-    "raw_rpc_proto_library",
-  )
+   # BUILD ...
+   load("@rules_proto//proto:defs.bzl", "proto_library")
+   load("@pigweed//pw_protobuf_compiler:pw_proto_library.bzl",
+     "nanopb_proto_library",
+     "nanopb_rpc_proto_library",
+     "pwpb_proto_library",
+     "raw_rpc_proto_library",
+   )
 
-  # Manages proto sources and dependencies.
-  proto_library(
-    name = "my_proto",
-    srcs = [
-      "my_protos/foo.proto",
-      "my_protos/bar.proto",
-    ]
-  )
+   # Manages proto sources and dependencies.
+   proto_library(
+     name = "my_proto",
+     srcs = [
+       "my_protos/foo.proto",
+       "my_protos/bar.proto",
+     ]
+   )
 
-  # Compiles dependent protos to C++.
-  pwpb_proto_library(
-    name = "my_proto_pwpb",
-    deps = [":my_proto"],
-  )
+   # Compiles dependent protos to C++.
+   pwpb_proto_library(
+     name = "my_proto_pwpb",
+     deps = [":my_proto"],
+   )
 
-  nanopb_proto_library(
-    name = "my_proto_nanopb",
-    deps = [":my_proto"],
-  )
+   nanopb_proto_library(
+     name = "my_proto_nanopb",
+     deps = [":my_proto"],
+   )
 
-  raw_rpc_proto_library(
-    name = "my_proto_raw_rpc",
-    deps = [":my_proto"],
-  )
+   raw_rpc_proto_library(
+     name = "my_proto_raw_rpc",
+     deps = [":my_proto"],
+   )
 
-  nanopb_rpc_proto_library(
-    name = "my_proto_nanopb_rpc",
-    nanopb_proto_library_deps = [":my_proto_nanopb"],
-    deps = [":my_proto"],
-  )
+   nanopb_rpc_proto_library(
+     name = "my_proto_nanopb_rpc",
+     nanopb_proto_library_deps = [":my_proto_nanopb"],
+     deps = [":my_proto"],
+   )
 
-  # Library that depends on only pw_protobuf generated proto targets.
-  pw_cc_library(
-    name = "my_proto_only_lib",
-    srcs = ["my/proto_only.cc"],
-    deps = [":my_proto_pwpb"],
-  )
+   # Library that depends on only pw_protobuf generated proto targets.
+   pw_cc_library(
+     name = "my_proto_only_lib",
+     srcs = ["my/proto_only.cc"],
+     deps = [":my_proto_pwpb"],
+   )
 
-  # Library that depends on only Nanopb generated proto targets.
-  pw_cc_library(
-    name = "my_nanopb_only_lib",
-    srcs = ["my/nanopb_only.cc"],
-    deps = [":my_proto_nanopb"],
-  )
+   # Library that depends on only Nanopb generated proto targets.
+   pw_cc_library(
+     name = "my_nanopb_only_lib",
+     srcs = ["my/nanopb_only.cc"],
+     deps = [":my_proto_nanopb"],
+   )
 
-  # Library that depends on pw_protobuf and pw_rpc/raw.
-  pw_cc_library(
-    name = "my_raw_rpc_lib",
-    srcs = ["my/raw_rpc.cc"],
-    deps = [
-      ":my_proto_pwpb",
-      ":my_proto_raw_rpc",
-    ],
-  )
-  pw_cc_library(
-    name = "my_nanopb_rpc_lib",
-    srcs = ["my/proto_only.cc"],
-    deps = [
-      ":my_proto_nanopb_rpc",
-    ],
-  )
-
+   # Library that depends on pw_protobuf and pw_rpc/raw.
+   pw_cc_library(
+     name = "my_raw_rpc_lib",
+     srcs = ["my/raw_rpc.cc"],
+     deps = [
+       ":my_proto_pwpb",
+       ":my_proto_raw_rpc",
+     ],
+   )
+   pw_cc_library(
+     name = "my_nanopb_rpc_lib",
+     srcs = ["my/proto_only.cc"],
+     deps = [
+       ":my_proto_nanopb_rpc",
+     ],
+   )
 
 From ``my/lib.cc`` you can now include the generated headers.
 e.g.
 
 .. code:: cpp
 
-  #include "my_protos/bar.pwpb.h"
-  // and/or RPC headers
-  #include "my_protos/bar.raw_rpc.pb.h
-  // or
-  #include "my_protos/bar.nanopb_rpc.pb.h"
+   #include "my_protos/bar.pwpb.h"
+   // and/or RPC headers
+   #include "my_protos/bar.raw_rpc.pb.h
+   // or
+   #include "my_protos/bar.nanopb_rpc.pb.h"
 
 
 Why isn't there one rule to generate all the code?
diff --git a/pw_random/docs.rst b/pw_random/docs.rst
index 20ea0b0..26e0559 100644
--- a/pw_random/docs.rst
+++ b/pw_random/docs.rst
@@ -62,9 +62,9 @@
 
 For more information, see:
 
- * https://en.wikipedia.org/wiki/Xorshift
- * https://www.jstatsoft.org/article/view/v008i14
- * http://vigna.di.unimi.it/ftp/papers/xorshift.pdf
+* https://en.wikipedia.org/wiki/Xorshift
+* https://www.jstatsoft.org/article/view/v008i14
+* http://vigna.di.unimi.it/ftp/papers/xorshift.pdf
 
 -----------
 Future Work
diff --git a/pw_software_update/design.rst b/pw_software_update/design.rst
index b431a91..81fa1b2 100644
--- a/pw_software_update/design.rst
+++ b/pw_software_update/design.rst
@@ -23,26 +23,28 @@
 
 .. mermaid::
 
-       flowchart LR
-              A[/Source/] --> |Build| B[/Target files/]
-              B --> |Assemble & Sign| C[(Update bundle)]
-              C --> |Publish| D[(Available updates)]
-              D --> |OTA| E[Device]
+   flowchart LR
+          A[/Source/] --> |Build| B[/Target files/]
+          B --> |Assemble & Sign| C[(Update bundle)]
+          C --> |Publish| D[(Available updates)]
+          D --> |OTA| E[Device]
 
 Update bundles
 ^^^^^^^^^^^^^^
 
 Update bundles represent software releases packaged ready for delivery. A bundle
-is essentially an archived folder matching the following structure::
+is essentially an archived folder matching the following structure:
 
-  /
-  ├── root_metadata
-  ├── targets_metadata
-  └── targets
-      ├── release_notes.txt
-      ├── manifest.txt
-      ├── rtos.bin
-      └── app.bin
+.. code-block:: text
+
+   /
+   ├── root_metadata
+   ├── targets_metadata
+   └── targets
+       ├── release_notes.txt
+       ├── manifest.txt
+       ├── rtos.bin
+       └── app.bin
 
 Bundles are encoded as serialized "protocol buffers".
 
@@ -55,10 +57,10 @@
 
 .. mermaid::
 
-       flowchart LR
-              A[Verified boot] --> |Embed & Verify| B[/Root key/]
-              B --> |Delegate & Rotate| C[/Targets key/]
-              C --> |Sign| D[/Target files/]
+   flowchart LR
+          A[Verified boot] --> |Embed & Verify| B[/Root key/]
+          B --> |Delegate & Rotate| C[/Targets key/]
+          C --> |Sign| D[/Target files/]
 
 
 The "root" role delegates the "targets" role to directly authorize each release.
@@ -72,7 +74,6 @@
 
 Signing service
 ^^^^^^^^^^^^^^^
-
 Production signing keys MUST be kept secure and clean. That means we must
 carefully control access, log usage details, and revoke the key if it was
 (accidentally) used to sign a "questionable" build.
@@ -81,18 +82,18 @@
 
 .. mermaid::
 
-       sequenceDiagram
-              actor Releaser
+   sequenceDiagram
+     actor Releaser
 
-              Releaser->>Signer: Sign my bundle with my key, please.
+     Releaser->>Signer: Sign my bundle with my key, please.
 
-              activate Signer
+     activate Signer
 
-              Signer->>Signer: Check permission.
-              Signer->>Signer: Validate & sign bundle.
-              Signer->>Signer: Log action. Email alerts.
-              Signer-->>Releaser: Done!
-              deactivate Signer
+     Signer->>Signer: Check permission.
+     Signer->>Signer: Validate & sign bundle.
+     Signer->>Signer: Log action. Email alerts.
+     Signer-->>Releaser: Done!
+     deactivate Signer
 
 We don't yet have a public-facing service. External users should source their
 own solution.
@@ -102,9 +103,8 @@
 
 .. mermaid::
 
-       flowchart LR
-              A[(Incoming bundle)] --> |UpdateBundleAccessor| B[/Verified target files/]
-
+   flowchart LR
+     A[(Incoming bundle)] --> |UpdateBundleAccessor| B[/Verified target files/]
 
 The :cpp:type:`UpdateBundleAccessor` decodes, verifies, and exposes the target
 files from an incoming bundle. This class hides the details of the bundle
@@ -122,43 +122,43 @@
 
 .. mermaid::
 
-       stateDiagram-v2
-       direction LR
+   stateDiagram-v2
+   direction LR
 
-       [*] --> Inactive
+   [*] --> Inactive
 
-       Inactive --> Transferring: Start()
-       Inactive --> Finished: Start() error
+   Inactive --> Transferring: Start()
+   Inactive --> Finished: Start() error
 
-       Transferring --> Transferring: GetStatus()
-       Transferring --> Transferred
-       Transferring --> Aborting: Abort()
-       Transferring --> Finished: Transfer error
+   Transferring --> Transferring: GetStatus()
+   Transferring --> Transferred
+   Transferring --> Aborting: Abort()
+   Transferring --> Finished: Transfer error
 
-       Transferred --> Transferred: GetStatus()
-       Transferred --> Verifying: Verify()
-       Transferred --> Verifying: Apply()
-       Transferred --> Aborting: Abort()
+   Transferred --> Transferred: GetStatus()
+   Transferred --> Verifying: Verify()
+   Transferred --> Verifying: Apply()
+   Transferred --> Aborting: Abort()
 
-       Verifying --> Verifying: GetStatus()
-       Verifying --> Verified
-       Verifying --> Aborting: Abort()
+   Verifying --> Verifying: GetStatus()
+   Verifying --> Verified
+   Verifying --> Aborting: Abort()
 
-       Verified --> Verified: GetStatus()
-       Verified --> Applying: Apply()
-       Verified --> Aborting: Abort()
+   Verified --> Verified: GetStatus()
+   Verified --> Applying: Apply()
+   Verified --> Aborting: Abort()
 
-       Applying --> Applying: GetStatus()
-       Applying --> Finished: Apply() OK
-       Applying --> Finished: Apply() error
+   Applying --> Applying: GetStatus()
+   Applying --> Finished: Apply() OK
+   Applying --> Finished: Apply() error
 
-       Aborting --> Aborting: GetStatus()
-       Aborting --> Finished: Abort() OK
-       Aborting --> Finished: Abort() error
+   Aborting --> Aborting: GetStatus()
+   Aborting --> Finished: Abort() OK
+   Aborting --> Finished: Abort() error
 
-       Finished --> Finished: GetStatus()
-       Finished --> Inactive: Reset()
-       Finished --> Finished: Reset() error
+   Finished --> Finished: GetStatus()
+   Finished --> Inactive: Reset()
+   Finished --> Finished: Reset() error
 
 
 Tooling
@@ -169,37 +169,36 @@
 
 The python package
 ~~~~~~~~~~~~~~~~~~
-
 ``pw_software_update`` comes with a python package of the same name, providing
 the following functionalities.
 
-  - Local signing key generation for development.
-  - TUF root metadata generation and signing.
-  - Bundle generation, signing, and verification.
-  - Signing server integration.
+- Local signing key generation for development.
+- TUF root metadata generation and signing.
+- Bundle generation, signing, and verification.
+- Signing server integration.
 
 A typical use of the package is for build system integration.
 
-.. code:: python
+.. code-block:: text
 
-       Help on package pw_software_update:
+   Help on package pw_software_update:
 
-       NAME
-              pw_software_update - pw_software_update
+   NAME
+          pw_software_update - pw_software_update
 
-       PACKAGE CONTENTS
-              bundled_update_pb2
-              cli
-              dev_sign
-              generate_test_bundle
-              keys
-              metadata
-              remote_sign
-              root_metadata
-              tuf_pb2
-              update_bundle
-              update_bundle_pb2
-              verify
+   PACKAGE CONTENTS
+          bundled_update_pb2
+          cli
+          dev_sign
+          generate_test_bundle
+          keys
+          metadata
+          remote_sign
+          root_metadata
+          tuf_pb2
+          update_bundle
+          update_bundle_pb2
+          verify
 
 
 The command line utility
@@ -213,24 +212,24 @@
 one. In the future you will be able to use the CLI to update a reference
 target.
 
-.. code:: bash
+.. code-block:: text
 
-       usage: pw update [sub-commands]
+   usage: pw update [sub-commands]
 
-       sub-commands:
+   sub-commands:
 
-              generate-key
-              create-root-metadata
-              sign-root-metadata
-              inspect-root-metadata
-              create-empty-bundle
-              add-root-metadata-to-bundle
-              add-file-to-bundle
-              sign-bundle
-              inspect-bundle
+          generate-key
+          create-root-metadata
+          sign-root-metadata
+          inspect-root-metadata
+          create-empty-bundle
+          add-root-metadata-to-bundle
+          add-file-to-bundle
+          sign-bundle
+          inspect-bundle
 
-       options:
-              -h, --help            show this help message and exit
+   options:
+          -h, --help            show this help message and exit
 
 
 To learn more, see :ref:`module-pw_software_update-cli`.
diff --git a/pw_status/docs.rst b/pw_status/docs.rst
index 3453857..3432361 100644
--- a/pw_status/docs.rst
+++ b/pw_status/docs.rst
@@ -392,21 +392,21 @@
 
 .. code-block:: cpp
 
-  Status overall_status;
-  for (Sector& sector : sectors) {
-    Status erase_status = sector.Erase();
-    if (!overall_status.ok()) {
-      overall_status = erase_status;
-    }
+   Status overall_status;
+   for (Sector& sector : sectors) {
+     Status erase_status = sector.Erase();
+     if (!overall_status.ok()) {
+       overall_status = erase_status;
+     }
 
-    if (erase_status.ok()) {
-      Status header_write_status = sector.WriteHeader();
-      if (!overall_status.ok()) {
-        overall_status = header_write_status;
-      }
-    }
-  }
-  return overall_status;
+     if (erase_status.ok()) {
+       Status header_write_status = sector.WriteHeader();
+       if (!overall_status.ok()) {
+         overall_status = header_write_status;
+       }
+     }
+   }
+   return overall_status;
 
 :cpp:class:`pw::Status` has a :cpp:func:`pw::Status::Update()` helper function
 that does exactly this to reduce visual clutter and succinctly highlight the
@@ -414,16 +414,16 @@
 
 .. code-block:: cpp
 
-  Status overall_status;
-  for (Sector& sector : sectors) {
-    Status erase_status = sector.Erase();
-    overall_status.Update(erase_status);
+   Status overall_status;
+   for (Sector& sector : sectors) {
+     Status erase_status = sector.Erase();
+     overall_status.Update(erase_status);
 
-    if (erase_status.ok()) {
-      overall_status.Update(sector.WriteHeader());
-    }
-  }
-  return overall_status;
+     if (erase_status.ok()) {
+       overall_status.Update(sector.WriteHeader());
+     }
+   }
+   return overall_status;
 
 Unused result warnings
 ----------------------
@@ -460,16 +460,16 @@
 ``pw::StatusWithSize`` values may be created with functions similar to
 ``pw::Status``. For example,
 
-  .. code-block:: cpp
+.. code-block:: cpp
 
-    // An OK StatusWithSize with a size of 123.
-    StatusWithSize(123)
+   // An OK StatusWithSize with a size of 123.
+   StatusWithSize(123)
 
-    // A NOT_FOUND StatusWithSize with a size of 0.
-    StatusWithSize::NotFound()
+   // A NOT_FOUND StatusWithSize with a size of 0.
+   StatusWithSize::NotFound()
 
-    // A RESOURCE_EXHAUSTED StatusWithSize with a size of 10.
-    StatusWithSize::ResourceExhausted(10)
+   // A RESOURCE_EXHAUSTED StatusWithSize with a size of 10.
+   StatusWithSize::ResourceExhausted(10)
 
 ------
 PW_TRY
@@ -483,19 +483,19 @@
 
 .. code-block:: cpp
 
-  Status PwTryExample() {
-    PW_TRY(FunctionThatReturnsStatus());
-    PW_TRY(FunctionThatReturnsStatusWithSize());
+   Status PwTryExample() {
+     PW_TRY(FunctionThatReturnsStatus());
+     PW_TRY(FunctionThatReturnsStatusWithSize());
 
-    // Do something, only executed if both functions above return OK.
-  }
+     // Do something, only executed if both functions above return OK.
+   }
 
-  StatusWithSize PwTryWithSizeExample() {
-    PW_TRY_WITH_SIZE(FunctionThatReturnsStatus());
-    PW_TRY_WITH_SIZE(FunctionThatReturnsStatusWithSize());
+   StatusWithSize PwTryWithSizeExample() {
+     PW_TRY_WITH_SIZE(FunctionThatReturnsStatus());
+     PW_TRY_WITH_SIZE(FunctionThatReturnsStatusWithSize());
 
-    // Do something, only executed if both functions above return OK.
-  }
+     // Do something, only executed if both functions above return OK.
+   }
 
 ``PW_TRY_ASSIGN`` is for working with ``StatusWithSize`` objects in in functions
 that return Status. It is similar to ``PW_TRY`` with the addition of assigning
@@ -503,13 +503,13 @@
 
 .. code-block:: cpp
 
-  Status PwTryAssignExample() {
-    size_t size_value
-    PW_TRY_ASSIGN(size_value, FunctionThatReturnsStatusWithSize());
+   Status PwTryAssignExample() {
+     size_t size_value
+     PW_TRY_ASSIGN(size_value, FunctionThatReturnsStatusWithSize());
 
-    // Do something that uses size_value. size_value is only assigned and this
-    // following code executed if the PW_TRY_ASSIGN function above returns OK.
-  }
+     // Do something that uses size_value. size_value is only assigned and this
+     // following code executed if the PW_TRY_ASSIGN function above returns OK.
+   }
 
 ------
 Zephyr
diff --git a/pw_sys_io/docs.rst b/pw_sys_io/docs.rst
index 33d63e6..4a12573 100644
--- a/pw_sys_io/docs.rst
+++ b/pw_sys_io/docs.rst
@@ -30,9 +30,9 @@
 =====
 This module requires relatively minimal setup:
 
-  1. Choose a ``pw_sys_io`` backend, or write one yourself.
-  2. If using GN build, Specify the ``pw_sys_io_BACKEND`` GN build arg to point
-     the library that provides a ``pw_sys_io`` backend.
+1. Choose a ``pw_sys_io`` backend, or write one yourself.
+2. If using GN build, Specify the ``pw_sys_io_BACKEND`` GN build arg to point
+   the library that provides a ``pw_sys_io`` backend.
 
 Module usage
 ============
@@ -50,6 +50,7 @@
 
 Dependencies
 ============
-  * pw_sys_io_backend
-  * pw_span
-  * pw_status
+- :ref:`module-pw_sys_io`
+- :ref:`module-pw_span`
+- :ref:`module-pw_status`
+
diff --git a/pw_sys_io_ambiq_sdk/docs.rst b/pw_sys_io_ambiq_sdk/docs.rst
index ae7c065..fef2be4 100644
--- a/pw_sys_io_ambiq_sdk/docs.rst
+++ b/pw_sys_io_ambiq_sdk/docs.rst
@@ -1,9 +1,8 @@
 .. _module-pw_sys_io_ambiq_sdk:
 
-===============================
+===================
 pw_sys_io_ambiq_sdk
-===============================
-
+===================
 ``pw_sys_io_ambiq_sdk`` implements the ``pw_sys_io`` facade over UART using the
 Ambiq Suite SDK HAL.
 
@@ -13,11 +12,11 @@
 =====
 This module requires relatively minimal setup:
 
-  1. Write code against the ``pw_sys_io`` facade.
-  2. Specify the ``dir_pw_sys_io_backend`` GN global variable to point to this
-     backend.
-  3. Call ``pw_sys_io_Init()`` during init so the UART is properly initialized
-     and configured.
+1. Write code against the ``pw_sys_io`` facade.
+2. Specify the ``dir_pw_sys_io_backend`` GN global variable to point to this
+   backend.
+3. Call ``pw_sys_io_Init()`` during init so the UART is properly initialized and
+   configured.
 
 The UART peripheral and the GPIO pins are defined in the ``am_bsp.h`` file. Make sure
 that the build argument ``pw_third_party_ambiq_PRODUCT`` is set correctly so that
diff --git a/pw_sys_io_arduino/docs.rst b/pw_sys_io_arduino/docs.rst
index 79c533d..0cc321b 100644
--- a/pw_sys_io_arduino/docs.rst
+++ b/pw_sys_io_arduino/docs.rst
@@ -12,11 +12,10 @@
 
 .. code-block:: cpp
 
-  Serial.begin(115200);
+   Serial.begin(115200);
 
-  // Wait for serial port to be available
-  while (!Serial) {
-  }
+   // Wait for serial port to be available
+   while (!Serial) {}
 
 After ``Serial.begin(115200)`` it will busy wait until a host connects to the
 serial port.
diff --git a/pw_sys_io_baremetal_lm3s6965evb/docs.rst b/pw_sys_io_baremetal_lm3s6965evb/docs.rst
index a865373..fc99395 100644
--- a/pw_sys_io_baremetal_lm3s6965evb/docs.rst
+++ b/pw_sys_io_baremetal_lm3s6965evb/docs.rst
@@ -6,4 +6,4 @@
 
 .. warning::
 
-  This documentation is under construction.
+   This documentation is under construction.
diff --git a/pw_sys_io_baremetal_stm32f429/docs.rst b/pw_sys_io_baremetal_stm32f429/docs.rst
index 1f1fe08..41f2633 100644
--- a/pw_sys_io_baremetal_stm32f429/docs.rst
+++ b/pw_sys_io_baremetal_stm32f429/docs.rst
@@ -3,7 +3,6 @@
 -----------------------------
 pw_sys_io_baremetal_stm32f429
 -----------------------------
-
 ``pw_sys_io_baremetal_stm32f429`` implements the ``pw_sys_io`` facade over
 UART.
 
@@ -21,16 +20,16 @@
 =====
 This module requires relatively minimal setup:
 
-  1. Write code against the ``pw_sys_io`` facade.
-  2. Specify the ``dir_pw_sys_io_backend`` GN global variable to point to this
-     backend.
-  3. Build an executable with a main() function using a toolchain that
-     supports Cortex-M4.
+1. Write code against the ``pw_sys_io`` facade.
+2. Specify the ``dir_pw_sys_io_backend`` GN global variable to point to this
+   backend.
+3. Build an executable with a main() function using a toolchain that
+   supports Cortex-M4.
 
 .. note::
-  This module provides early firmware init and a linker script, so it will
-  conflict with other modules that do any early device init or provide a linker
-  script.
+   This module provides early firmware init and a linker script, so it will
+   conflict with other modules that do any early device init or provide a linker
+   script.
 
 Module usage
 ============
@@ -47,15 +46,15 @@
 
 .. code-block:: text
 
-  --USB Serial--+    +-----STM32F429 MCU-----
-                |    |
-             TX o--->o PA10/USART1_RX
-                |    |
-             RX o<---o PA9/USART1_TX
-                |    |
-  --------------+    +-----------------------
+   --USB Serial--+    +-----STM32F429 MCU-----
+                 |    |
+              TX o--->o PA10/USART1_RX
+                 |    |
+              RX o<---o PA9/USART1_TX
+                 |    |
+   --------------+    +-----------------------
 
 Dependencies
 ============
-  * ``pw_sys_io`` facade
-  * ``pw_preprocessor`` module
+- :ref:`module-pw_sys_io`
+- :ref:`module-pw_preprocessor`
diff --git a/pw_sys_io_emcraft_sf2/docs.rst b/pw_sys_io_emcraft_sf2/docs.rst
index 66ef6c9..948588d 100644
--- a/pw_sys_io_emcraft_sf2/docs.rst
+++ b/pw_sys_io_emcraft_sf2/docs.rst
@@ -19,17 +19,17 @@
 =====
 This module requires relatively minimal setup:
 
-  1. Write code against the ``pw_sys_io`` facade.
-  2. Specify the ``dir_pw_sys_io_backend`` GN global variable to point to this
-     backend.
-  3. pw_sys_io_Init() provided by this module needs to be called in early boot
-     to get pw_sys_io into a working state.
-  4. Build an executable with a main() function using a toolchain that
-     supports Cortex-M3.
+1. Write code against the ``pw_sys_io`` facade.
+2. Specify the ``dir_pw_sys_io_backend`` GN global variable to point to this
+   backend.
+3. pw_sys_io_Init() provided by this module needs to be called in early boot
+   to get pw_sys_io into a working state.
+4. Build an executable with a main() function using a toolchain that
+   supports Cortex-M3.
 
 .. note::
-  This module provides early firmware init, so it will conflict with other
-  modules that do any early device init.
+   This module provides early firmware init, so it will conflict with other
+   modules that do any early device init.
 
 Module usage
 ============
@@ -40,5 +40,5 @@
 
 Dependencies
 ============
-  * ``pw_sys_io`` facade
-  * ``pw_preprocessor`` module
+- :ref:`module-pw_sys_io`
+- :ref:`module-pw_preprocessor`
diff --git a/pw_sys_io_mcuxpresso/docs.rst b/pw_sys_io_mcuxpresso/docs.rst
index a237611..fc30fc1 100644
--- a/pw_sys_io_mcuxpresso/docs.rst
+++ b/pw_sys_io_mcuxpresso/docs.rst
@@ -12,13 +12,13 @@
 =====
 This module requires a little setup:
 
- 1. Use ``pw_build_mcuxpresso`` to create a ``pw_source_set`` for an
-    MCUXpresso SDK.
- 2. Include the debug console component in this SDK definition.
- 3. Specify the ``pw_third_party_mcuxpresso_SDK`` GN global variable to specify
-    the name of this source set.
- 4. Use a target that calls ``pw_sys_io_mcuxpresso_Init`` in
-    ``pw_boot_PreMainInit`` or similar.
+1. Use ``pw_build_mcuxpresso`` to create a ``pw_source_set`` for an
+   MCUXpresso SDK.
+2. Include the debug console component in this SDK definition.
+3. Specify the ``pw_third_party_mcuxpresso_SDK`` GN global variable to specify
+   the name of this source set.
+4. Use a target that calls ``pw_sys_io_mcuxpresso_Init`` in
+   ``pw_boot_PreMainInit`` or similar.
 
 The name of the SDK source set must be set in the
 "pw_third_party_mcuxpresso_SDK" GN arg
@@ -31,7 +31,7 @@
 
 .. c:macro:: DEBUG_CONSOLE_TRANSFER_NON_BLOCKING
 
-  Whether the MCUXpresso debug console supports non-blocking transfers. The
-  default will depend on your SDK configuration.
+   Whether the MCUXpresso debug console supports non-blocking transfers. The
+   default will depend on your SDK configuration.
 
-  Enabling this adds support for ``pw::sys_io::TryReadByte``.
+   Enabling this adds support for ``pw::sys_io::TryReadByte``.
diff --git a/pw_sys_io_stdio/docs.rst b/pw_sys_io_stdio/docs.rst
index 7280656..eaa45af 100644
--- a/pw_sys_io_stdio/docs.rst
+++ b/pw_sys_io_stdio/docs.rst
@@ -8,7 +8,6 @@
 
 Why not just use stdio directly?
 --------------------------------
-
 The nice thing about using ``pw_sys_io`` is that it's rather easy to get a
 board up and running with a target-specific backend. This means when drafting
 out a quick application you can write it against ``pw_sys_io`` and, with some
@@ -21,8 +20,8 @@
 =====
 This module requires relatively minimal setup:
 
-  1. Write code against the ``pw_sys_io`` facade.
-  2. Direct the ``pw_sys_io_BACKEND`` GN build arg to point to this backend.
+1. Write code against the ``pw_sys_io`` facade.
+2. Direct the ``pw_sys_io_BACKEND`` GN build arg to point to this backend.
 
 Module usage
 ============
@@ -31,4 +30,4 @@
 
 Dependencies
 ============
-  * ``pw_sys_io`` facade
+- :ref:`module-pw_sys_io`
diff --git a/pw_sys_io_stm32cube/docs.rst b/pw_sys_io_stm32cube/docs.rst
index e4155d6..a470fbb 100644
--- a/pw_sys_io_stm32cube/docs.rst
+++ b/pw_sys_io_stm32cube/docs.rst
@@ -13,11 +13,11 @@
 =====
 This module requires relatively minimal setup:
 
-  1. Write code against the ``pw_sys_io`` facade.
-  2. Specify the ``dir_pw_sys_io_backend`` GN global variable to point to this
-     backend.
-  3. Call ``pw_sys_io_Init()`` during init so the UART is properly initialized
-     and configured.
+1. Write code against the ``pw_sys_io`` facade.
+2. Specify the ``dir_pw_sys_io_backend`` GN global variable to point to this
+   backend.
+3. Call ``pw_sys_io_Init()`` during init so the UART is properly initialized
+   and configured.
 
 For devices other than the STM32F429I-DISC1, this module will need to be
 configured to use the appropriate GPIO pins and USART peripheral.
@@ -83,10 +83,10 @@
 
 .. code-block:: text
 
-  --USB Serial--+    +-----STM32F429 MCU-----
-                |    |
-             TX o--->o PA10/USART1_RX
-                |    |
-             RX o<---o PA9/USART1_TX
-                |    |
-  --------------+    +-----------------------
+   --USB Serial--+    +-----STM32F429 MCU-----
+                 |    |
+              TX o--->o PA10/USART1_RX
+                 |    |
+              RX o<---o PA9/USART1_TX
+                 |    |
+   --------------+    +-----------------------
diff --git a/pw_thread_threadx/docs.rst b/pw_thread_threadx/docs.rst
index 026ed2b..d49c133 100644
--- a/pw_thread_threadx/docs.rst
+++ b/pw_thread_threadx/docs.rst
@@ -6,7 +6,7 @@
 This is a set of backends for pw_thread based on ThreadX.
 
 .. Warning::
-  This module is still under construction, the API is not yet stable.
+   This module is still under construction, the API is not yet stable.
 
 -----------------------
 Thread Creation Backend
@@ -21,48 +21,48 @@
 
 .. code-block:: cpp
 
-  #include "pw_thread/detached_thread.h"
-  #include "pw_thread_threadx/config.h"
-  #include "pw_thread_threadx/context.h"
-  #include "pw_thread_threadx/options.h"
-  #include "tx_api.h"
+   #include "pw_thread/detached_thread.h"
+   #include "pw_thread_threadx/config.h"
+   #include "pw_thread_threadx/context.h"
+   #include "pw_thread_threadx/options.h"
+   #include "tx_api.h"
 
-  constexpr UINT kFooPriority =
-      pw::thread::threadx::config::kDefaultPriority;
-  constexpr ULONG kFooTimeSliceInterval =
-      pw::thread::threadx::config::kDefaultTimeSliceInterval;
-  constexpr size_t kFooStackSizeWords =
-      pw::thread::threadx::config::kDefaultStackSizeWords;
+   constexpr UINT kFooPriority =
+       pw::thread::threadx::config::kDefaultPriority;
+   constexpr ULONG kFooTimeSliceInterval =
+       pw::thread::threadx::config::kDefaultTimeSliceInterval;
+   constexpr size_t kFooStackSizeWords =
+       pw::thread::threadx::config::kDefaultStackSizeWords;
 
-  pw::thread::threadx::ContextWithStack<kFooStackSizeWords>
-      example_thread_context;
-  void StartExampleThread() {
-    pw::thread::DetachedThread(
-        pw::thread::threadx::Options()
-            .set_name("example_thread")
-            .set_priority(kFooPriority)
-            .set_time_slice_interval(kFooTimeSliceInterval)
-            .set_context(example_thread_context),
-        example_thread_function);
-  }
+   pw::thread::threadx::ContextWithStack<kFooStackSizeWords>
+       example_thread_context;
+   void StartExampleThread() {
+     pw::thread::DetachedThread(
+         pw::thread::threadx::Options()
+             .set_name("example_thread")
+             .set_priority(kFooPriority)
+             .set_time_slice_interval(kFooTimeSliceInterval)
+             .set_context(example_thread_context),
+         example_thread_function);
+   }
 
 .. list-table::
 
-  * - :ref:`module-pw_thread` Facade
-    - Backend Target
-    - Description
-  * - ``pw_thread:id``
-    - ``pw_thread_threadx:id``
-    - Thread identification.
-  * - ``pw_thread:yield``
-    - ``pw_thread_threadx:yield``
-    - Thread scheduler yielding.
-  * - ``pw_thread:sleep``
-    - ``pw_thread_threadx:sleep``
-    - Thread scheduler sleeping.
-  * - ``pw_thread:thread``
-    - ``pw_thread_threadx:thread``
-    - Thread creation.
+   * - :ref:`module-pw_thread` Facade
+     - Backend Target
+     - Description
+   * - ``pw_thread:id``
+     - ``pw_thread_threadx:id``
+     - Thread identification.
+   * - ``pw_thread:yield``
+     - ``pw_thread_threadx:yield``
+     - Thread scheduler yielding.
+   * - ``pw_thread:sleep``
+     - ``pw_thread_threadx:sleep``
+     - Thread scheduler sleeping.
+   * - ``pw_thread:thread``
+     - ``pw_thread_threadx:thread``
+     - Thread creation.
 
 Module Configuration Options
 ============================
@@ -73,111 +73,111 @@
 
 .. c:macro:: PW_THREAD_THREADX_CONFIG_JOINING_ENABLED
 
-  Whether thread joining is enabled. By default this is disabled.
+   Whether thread joining is enabled. By default this is disabled.
 
-  We suggest only enabling this when thread joining is required to minimize
-  the RAM and ROM cost of threads.
+   We suggest only enabling this when thread joining is required to minimize
+   the RAM and ROM cost of threads.
 
-  Enabling this grows the RAM footprint of every pw::thread::Thread as it adds
-  a TX_EVENT_FLAGS_GROUP to every thread's pw::thread::threadx::Context. In
-  addition, there is a minute ROM cost to construct and destroy this added
-  object.
+   Enabling this grows the RAM footprint of every pw::thread::Thread as it adds
+   a TX_EVENT_FLAGS_GROUP to every thread's pw::thread::threadx::Context. In
+   addition, there is a minute ROM cost to construct and destroy this added
+   object.
 
-  PW_THREAD_JOINING_ENABLED gets set to this value.
+   PW_THREAD_JOINING_ENABLED gets set to this value.
 
 .. c:macro:: PW_THREAD_THREADX_CONFIG_DEFAULT_STACK_SIZE_WORDS
 
-  The default stack size in words. By default this uses the minimal ThreadX
-  stack size.
+   The default stack size in words. By default this uses the minimal ThreadX
+   stack size.
 
 .. c:macro:: PW_THREAD_THREADX_CONFIG_MAX_THREAD_NAME_LEN
 
-  The maximum length of a thread's name, not including null termination. By
-  default this is arbitrarily set to 15. This results in an array of characters
-  which is this length + 1 bytes in every pw::thread::Thread's context.
+   The maximum length of a thread's name, not including null termination. By
+   default this is arbitrarily set to 15. This results in an array of characters
+   which is this length + 1 bytes in every pw::thread::Thread's context.
 
 .. c:macro:: PW_THREAD_THREADX_CONFIG_DEFAULT_TIME_SLICE_INTERVAL
 
-  The round robin time slice tick interval for threads at the same priority.
-  By default this is disabled as not all ports support this, using a value of 0
-  ticks.
+   The round robin time slice tick interval for threads at the same priority.
+   By default this is disabled as not all ports support this, using a value of 0
+   ticks.
 
 .. c:macro:: PW_THREAD_THREADX_CONFIG_MIN_PRIORITY
 
-  The minimum priority level, this is normally based on the number of priority
-  levels.
+   The minimum priority level, this is normally based on the number of priority
+   levels.
 
 .. c:macro:: PW_THREAD_THREADX_CONFIG_DEFAULT_PRIORITY
 
-  The default priority level. By default this uses the minimal ThreadX
-  priority level, given that 0 is the highest priority.
+   The default priority level. By default this uses the minimal ThreadX
+   priority level, given that 0 is the highest priority.
 
 .. c:macro:: PW_THREAD_THREADX_CONFIG_LOG_LEVEL
 
-  The log level to use for this module. Logs below this level are omitted.
+   The log level to use for this module. Logs below this level are omitted.
 
 ThreadX Thread Options
 ======================
 .. cpp:class:: pw::thread::threadx::Options
 
-  .. cpp:function:: set_name(const char* name)
+   .. cpp:function:: set_name(const char* name)
 
-     Sets the name for the ThreadX thread, note that this will be deep copied
-     into the context and may be truncated based on
-     ``PW_THREAD_THREADX_CONFIG_MAX_THREAD_NAME_LEN``.
+      Sets the name for the ThreadX thread, note that this will be deep copied
+      into the context and may be truncated based on
+      ``PW_THREAD_THREADX_CONFIG_MAX_THREAD_NAME_LEN``.
 
-  .. cpp:function:: set_priority(UINT priority)
+   .. cpp:function:: set_priority(UINT priority)
 
-     Sets the priority for the ThreadX thread from 0 through 31, where a value
-     of 0 represents the highest priority, see ThreadX tx_thread_create for
-     more detail.
+      Sets the priority for the ThreadX thread from 0 through 31, where a value
+      of 0 represents the highest priority, see ThreadX tx_thread_create for
+      more detail.
 
-     **Precondition**: priority <= ``PW_THREAD_THREADX_CONFIG_MIN_PRIORITY``.
+      **Precondition**: priority <= ``PW_THREAD_THREADX_CONFIG_MIN_PRIORITY``.
 
-  .. cpp:function:: set_preemption_threshold(UINT preemption_threshold)
+   .. cpp:function:: set_preemption_threshold(UINT preemption_threshold)
 
-     Optionally sets the preemption threshold for the ThreadX thread from 0
-     through 31.
+      Optionally sets the preemption threshold for the ThreadX thread from 0
+      through 31.
 
-     Only priorities higher than this level (i.e. lower number) are allowed to
-     preempt this thread. In other words this allows the thread to specify the
-     priority ceiling for disabling preemption. Threads that have a higher
-     priority than the ceiling are still allowed to preempt while those with
-     less than the ceiling are not allowed to preempt.
+      Only priorities higher than this level (i.e. lower number) are allowed to
+      preempt this thread. In other words this allows the thread to specify the
+      priority ceiling for disabling preemption. Threads that have a higher
+      priority than the ceiling are still allowed to preempt while those with
+      less than the ceiling are not allowed to preempt.
 
-     Not setting the preemption threshold or explicitly specifying a value
-     equal to the priority disables preemption threshold.
+      Not setting the preemption threshold or explicitly specifying a value
+      equal to the priority disables preemption threshold.
 
-     Time slicing is disabled while the preemption threshold is enabled, i.e.
-     not equal to the priority, even if a time slice interval was specified.
+      Time slicing is disabled while the preemption threshold is enabled, i.e.
+      not equal to the priority, even if a time slice interval was specified.
 
-     The preemption threshold can be adjusted at run time, this only sets the
-     initial threshold.
+      The preemption threshold can be adjusted at run time, this only sets the
+      initial threshold.
 
-     **Precondition**: preemption_threshold <= priority
+      **Precondition**: preemption_threshold <= priority
 
-  .. cpp:function:: set_time_slice_interval(UINT time_slice_interval)
+   .. cpp:function:: set_time_slice_interval(UINT time_slice_interval)
 
-     Sets the number of ticks this thread is allowed to run before other ready
-     threads of the same priority are given a chance to run.
+      Sets the number of ticks this thread is allowed to run before other ready
+      threads of the same priority are given a chance to run.
 
-     Time slicing is disabled while the preemption threshold is enabled, i.e.
-     not equal to the priority, even if a time slice interval was specified.
+      Time slicing is disabled while the preemption threshold is enabled, i.e.
+      not equal to the priority, even if a time slice interval was specified.
 
-     A value of ``TX_NO_TIME_SLICE`` (a value of 0) disables time-slicing of
-     this thread.
+      A value of ``TX_NO_TIME_SLICE`` (a value of 0) disables time-slicing of
+      this thread.
 
-     Using time slicing results in a slight amount of system overhead, threads
-     with a unique priority should consider ``TX_NO_TIME_SLICE``.
+      Using time slicing results in a slight amount of system overhead, threads
+      with a unique priority should consider ``TX_NO_TIME_SLICE``.
 
 
-  .. cpp:function:: set_context(pw::thread::embos::Context& context)
+   .. cpp:function:: set_context(pw::thread::embos::Context& context)
 
-     Set the pre-allocated context (all memory needed to run a thread). Note
-     that this is required for this thread creation backend! The Context can
-     either be constructed with an externally provided ``pw::span<ULONG>``
-     stack or the templated form of ``ContextWihtStack<kStackSizeWords`` can be
-     used.
+      Set the pre-allocated context (all memory needed to run a thread). Note
+      that this is required for this thread creation backend! The Context can
+      either be constructed with an externally provided ``pw::span<ULONG>``
+      stack or the templated form of ``ContextWihtStack<kStackSizeWords`` can be
+      used.
 
 -----------------------------
 Thread Identification Backend
@@ -234,18 +234,18 @@
 running thread must be provided for cases where the running thread is being
 captured. For ARM Cortex-M CPUs, you can do something like this:
 
-.. Code:: cpp
+.. code-block:: cpp
 
-  // Capture PSP.
-  void* stack_ptr = 0;
-  asm volatile("mrs %0, psp\n" : "=r"(stack_ptr));
-  pw::thread::ProcessThreadStackCallback cb =
-      [](pw::thread::proto::Thread::StreamEncoder& encoder,
-         pw::ConstByteSpan stack) -> pw::Status {
-    return encoder.WriteRawStack(stack);
-  };
-  pw::thread::threadx::SnapshotThread(my_thread, stack_ptr,
-                                      snapshot_encoder, cb);
+   // Capture PSP.
+   void* stack_ptr = 0;
+   asm volatile("mrs %0, psp\n" : "=r"(stack_ptr));
+   pw::thread::ProcessThreadStackCallback cb =
+       [](pw::thread::proto::Thread::StreamEncoder& encoder,
+          pw::ConstByteSpan stack) -> pw::Status {
+     return encoder.WriteRawStack(stack);
+   };
+   pw::thread::threadx::SnapshotThread(my_thread, stack_ptr,
+                                       snapshot_encoder, cb);
 
 ``SnapshotThreads()`` wraps the singular thread capture to instead captures
 all created threads to a ``pw::thread::proto::SnapshotThreadInfo`` message.
diff --git a/pw_tls_client/docs.rst b/pw_tls_client/docs.rst
index 78c9cf0..774abdc 100644
--- a/pw_tls_client/docs.rst
+++ b/pw_tls_client/docs.rst
@@ -16,18 +16,18 @@
 connection options. The list of supported configurations currently include:
 
 1. Host name of the target server. This will be used as the Server Name
-Indication(SNI) extension during TLS handshake.
+   Indication(SNI) extension during TLS handshake.
 
 2. User-implemented transport. The underlying transport for the TLS
-communication. It is an object that implements the interface of
-``pw::stream::ReaderWriter``.
+   communication. It is an object that implements the interface of
+   ``pw::stream::ReaderWriter``.
 
 The module will also provide mechanisms/APIs for users to specify sources of
 trust anchors, time and entropy. These are under construction.
 
 .. warning::
-  This module is under construction, not ready for use, and the documentation
-  is incomplete.
+   This module is under construction, not ready for use, and the documentation
+   is incomplete.
 
 Prerequisites
 =============
@@ -50,7 +50,7 @@
 
 .. code-block:: sh
 
-  pw package install chromium_verifier
+   pw package install chromium_verifier
 
 Then follow instruction for setting ``dir_pw_third_party_chromium_verifier`` to
 the path of the downloaded repo.
@@ -90,7 +90,7 @@
 
 .. code-block:: sh
 
-  pw package install crlset --force
+   pw package install crlset --force
 
 The `--force` option forces CRLSet to be always re-downloaded so that it is
 up-to-date. Project that are concerned about up-to-date CRLSet should always
@@ -103,14 +103,14 @@
 =====
 This module requires the following setup:
 
-  1. Choose a ``pw_tls_client`` backend, or write one yourself.
-  2. If using GN build, Specify the ``pw_tls_client_BACKEND`` GN build arg to
-     point the library that provides a ``pw_tls_client`` backend. To use the
-     MbedTLS backend, set variable ``pw_tls_client_BACKEND`` to
-     ``//pw_tls_client_mbedtls``. To use the BoringSSL backend, set it to
-     ``//pw_tls_client_boringssl``.
-  3. Provide a `pw_tls_client:entropy` backend. If using GN build, specify the
-     backend with variable ``pw_tls_client_ENTROPY_BACKEND``.
+1. Choose a ``pw_tls_client`` backend, or write one yourself.
+2. If using GN build, Specify the ``pw_tls_client_BACKEND`` GN build arg to
+   point the library that provides a ``pw_tls_client`` backend. To use the
+   MbedTLS backend, set variable ``pw_tls_client_BACKEND`` to
+   ``//pw_tls_client_mbedtls``. To use the BoringSSL backend, set it to
+   ``//pw_tls_client_boringssl``.
+3. Provide a `pw_tls_client:entropy` backend. If using GN build, specify the
+   backend with variable ``pw_tls_client_ENTROPY_BACKEND``.
 
 Module usage
 ============
@@ -122,111 +122,109 @@
 
 .. code-block:: cpp
 
-  // Host domain name
-  constexpr char kHost[] = "www.google.com";
+   // Host domain name
+   constexpr char kHost[] = "www.google.com";
 
-  constexpr int kPort = 443;
+   constexpr int kPort = 443;
 
-  // Server Name Indication.
-  constexpr const char* kServerNameIndication = kHost;
+   // Server Name Indication.
+   constexpr const char* kServerNameIndication = kHost;
 
-  // An example message to send.
-  constexpr char kHTTPRequest[] = "GET / HTTP/1.1\r\n\r\n";
+   // An example message to send.
+   constexpr char kHTTPRequest[] = "GET / HTTP/1.1\r\n\r\n";
 
-  // pw::stream::SocketStream doesn't accept host domain name as input. Thus we
-  // introduce this helper function for getting the IP address
-  pw::Status GetIPAddrFromHostName(std::string_view host, pw::span<char> ip) {
-    char null_terminated_host_name[256] = {0};
-    auto host_copy_status = pw::string::Copy(host, null_terminated_host_name);
-    if (!host_copy_status.ok()) {
-      return host_copy_status.status();
-    }
+   // pw::stream::SocketStream doesn't accept host domain name as input. Thus we
+   // introduce this helper function for getting the IP address
+   pw::Status GetIPAddrFromHostName(std::string_view host, pw::span<char> ip) {
+     char null_terminated_host_name[256] = {0};
+     auto host_copy_status = pw::string::Copy(host, null_terminated_host_name);
+     if (!host_copy_status.ok()) {
+       return host_copy_status.status();
+     }
 
-    struct hostent* ent = gethostbyname(null_terminated_host_name);
-    if (ent == NULL) {
-      return PW_STATUS_INTERNAL;
-    }
+     struct hostent* ent = gethostbyname(null_terminated_host_name);
+     if (ent == NULL) {
+       return PW_STATUS_INTERNAL;
+     }
 
-    in_addr** addr_list = reinterpret_cast<in_addr**>(ent->h_addr_list);
-    if (addr_list[0] == nullptr) {
-      return PW_STATUS_INTERNAL;
-    }
+     in_addr** addr_list = reinterpret_cast<in_addr**>(ent->h_addr_list);
+     if (addr_list[0] == nullptr) {
+       return PW_STATUS_INTERNAL;
+     }
 
-    auto ip_copy_status = pw::string::Copy(inet_ntoa(*addr_list[0]), ip);
-    if (!ip_copy_status.ok()) {
-      return ip_copy_status.status();
-    }
+     auto ip_copy_status = pw::string::Copy(inet_ntoa(*addr_list[0]), ip);
+     if (!ip_copy_status.ok()) {
+       return ip_copy_status.status();
+     }
 
-    return pw::OkStatus();
-  }
+     return pw::OkStatus();
+   }
 
-  int main() {
-    // Get the IP address of the target host.
-    char ip_address[64] = {0};
-    auto get_ip_status = GetIPAddrFromHostName(kHost, ip_address);
-    if (!get_ip_status.ok()) {
-      return 1;
-    }
+   int main() {
+     // Get the IP address of the target host.
+     char ip_address[64] = {0};
+     auto get_ip_status = GetIPAddrFromHostName(kHost, ip_address);
+     if (!get_ip_status.ok()) {
+       return 1;
+     }
 
-    // Use a socket stream as the transport.
-    pw::stream::SocketStream socket_stream;
+     // Use a socket stream as the transport.
+     pw::stream::SocketStream socket_stream;
 
-    // Connect the socket to the remote host.
-    auto socket_connect_status = socket_stream.Connect(ip_address, kPort);
-    if (!socket_connect_status.ok()) {
-      return 1;
-    }
+     // Connect the socket to the remote host.
+     auto socket_connect_status = socket_stream.Connect(ip_address, kPort);
+     if (!socket_connect_status.ok()) {
+       return 1;
+     }
 
-    // Create a TLS session. Register the transport.
-    auto options = pw::tls_client::SessionOptions()
-            .set_server_name(kServerNameIndication)
-            .set_transport(socket_stream);
-    auto tls_conn = pw::tls_client::Session::Create(options);
-    if (!tls_conn.ok()) {
-      // Handle errors.
-      return 1;
-    }
+     // Create a TLS session. Register the transport.
+     auto options = pw::tls_client::SessionOptions()
+             .set_server_name(kServerNameIndication)
+             .set_transport(socket_stream);
+     auto tls_conn = pw::tls_client::Session::Create(options);
+     if (!tls_conn.ok()) {
+       // Handle errors.
+       return 1;
+     }
 
-    auto open_status = tls_conn.value()->Open();
-    if (!open_status.ok()) {
-      // Inspect/handle error with open_status.code() and
-      // tls_conn.value()->GetLastTLSStatus().
-      return 1;
-    }
+     auto open_status = tls_conn.value()->Open();
+     if (!open_status.ok()) {
+       // Inspect/handle error with open_status.code() and
+       // tls_conn.value()->GetLastTLSStatus().
+       return 1;
+     }
 
-    auto write_status = tls_conn.value()->Write(pw::as_bytes(pw::span{kHTTPRequest}));
-    if (!write_status.ok()) {
-      // Inspect/handle error with write_status.code() and
-      // tls_conn.value()->GetLastTLSStatus().
-      return 0;
-    }
+     auto write_status = tls_conn.value()->Write(pw::as_bytes(pw::span{kHTTPRequest}));
+     if (!write_status.ok()) {
+       // Inspect/handle error with write_status.code() and
+       // tls_conn.value()->GetLastTLSStatus().
+       return 0;
+     }
 
-    // Listen for incoming data.
-    std::array<std::byte, 4096> buffer;
-    while (true) {
-      auto res = tls_conn.value()->Read(buffer);
-      if (!res.ok()) {
-        // Inspect/handle error with res.status().code() and
-        // tls_conn.value()->GetLastTLSStatus().
-        return 1;
-      }
+     // Listen for incoming data.
+     std::array<std::byte, 4096> buffer;
+     while (true) {
+       auto res = tls_conn.value()->Read(buffer);
+       if (!res.ok()) {
+         // Inspect/handle error with res.status().code() and
+         // tls_conn.value()->GetLastTLSStatus().
+         return 1;
+       }
 
-      // Process data in |buffer|. res.value() gives the span of read bytes.
-      // The following simply print to console.
-      if (res.value().size()) {
-        auto print_status = pw::sys_io::WriteBytes(res.value());
-        if (!print_status.ok()) {
-          return 1;
-        }
-      }
+       // Process data in |buffer|. res.value() gives the span of read bytes.
+       // The following simply print to console.
+       if (res.value().size()) {
+         auto print_status = pw::sys_io::WriteBytes(res.value());
+         if (!print_status.ok()) {
+           return 1;
+         }
+       }
 
-    }
-  }
+     }
+   }
 
 A list of other demos will be provided in ``//pw_tls_client/examples/``
 
-Warning
-============
-
-Open()/Read() APIs are synchronous for now. Support for
-non-blocking/asynchronous usage will be added in the future.
+.. warning::
+   Open()/Read() APIs are synchronous for now. Support for
+   non-blocking/asynchronous usage will be added in the future.
diff --git a/pw_unit_test/docs.rst b/pw_unit_test/docs.rst
index 5c3415a..b448e44 100644
--- a/pw_unit_test/docs.rst
+++ b/pw_unit_test/docs.rst
@@ -12,7 +12,7 @@
 
 .. note::
 
-  This documentation is currently incomplete.
+   This documentation is currently incomplete.
 
 -------------------------------------------
 pw_unit_test:light: GoogleTest for Embedded
@@ -35,20 +35,20 @@
 
 .. note::
 
-  Many of GoogleTest's more advanced features are not yet implemented. Missing
-  features include:
+   Many of GoogleTest's more advanced features are not yet implemented. Missing
+   features include:
 
-  * Any GoogleMock features (e.g. :c:macro:`EXPECT_THAT`)
-  * Floating point comparison macros (e.g. :c:macro:`EXPECT_FLOAT_EQ`)
-  * Death tests (e.g. :c:macro:`EXPECT_DEATH`); ``EXPECT_DEATH_IF_SUPPORTED``
-    does nothing but silently passes
-  * Value-parameterized tests
+   * Any GoogleMock features (e.g. :c:macro:`EXPECT_THAT`)
+   * Floating point comparison macros (e.g. :c:macro:`EXPECT_FLOAT_EQ`)
+   * Death tests (e.g. :c:macro:`EXPECT_DEATH`); ``EXPECT_DEATH_IF_SUPPORTED``
+     does nothing but silently passes
+   * Value-parameterized tests
 
-  To request a feature addition, please
-  `let us know <mailto:pigweed@googlegroups.com>`_.
+   To request a feature addition, please
+   `let us know <mailto:pigweed@googlegroups.com>`_.
 
-  See `Using upstream GoogleTest`_ below for information
-  about using upstream GoogleTest instead.
+   See `Using upstream GoogleTest`_ below for information
+   about using upstream GoogleTest instead.
 
 The EventHandler interface
 ==========================
@@ -735,23 +735,23 @@
 the `main` functions written for `pw_unit_test:light` to work with upstream
 GoogleTest without modification, as shown below.
 
-  .. code-block:: c++
+.. code-block:: c++
 
-    #include "gtest/gtest.h"
-    #include "pw_unit_test/logging_event_handler.h"
+   #include "gtest/gtest.h"
+   #include "pw_unit_test/logging_event_handler.h"
 
-    int main() {
-      testing::InitGoogleTest();
-      pw::unit_test::LoggingEventHandler logger;
-      pw::unit_test::RegisterEventHandler(&logger);
-      return RUN_ALL_TESTS();
-    }
+   int main() {
+     testing::InitGoogleTest();
+     pw::unit_test::LoggingEventHandler logger;
+     pw::unit_test::RegisterEventHandler(&logger);
+     return RUN_ALL_TESTS();
+   }
 
 .. cpp:namespace-push:: pw::unit_test
 
 .. cpp:class:: GoogleTestHandlerAdapter
 
-  A GoogleTest Event Listener that fires GoogleTest emitted events to an
-  appropriate ``EventHandler``.
+   A GoogleTest Event Listener that fires GoogleTest emitted events to an
+   appropriate ``EventHandler``.
 
 .. cpp::namespace-pop::
diff --git a/pw_work_queue/docs.rst b/pw_work_queue/docs.rst
index 7ae6efa..9ea3bd8 100644
--- a/pw_work_queue/docs.rst
+++ b/pw_work_queue/docs.rst
@@ -7,7 +7,7 @@
 executed by another thread.
 
 .. Warning::
-  This module is still under construction, the API is not yet stable.
+   This module is still under construction, the API is not yet stable.
 
 ---------
 WorkQueue
@@ -27,7 +27,7 @@
 buffer passed into the constructor or by using the templated
 ``pw::work_queue::WorkQueueWithBuffer`` helper.
 
-.. Note:: While the queue is full, the queue will not accept further work.
+.. note:: While the queue is full, the queue will not accept further work.
 
 Cooperative Thread Cancellation
 ===============================
@@ -36,69 +36,69 @@
 ``RequestStop()`` API for cooperative cancellation which should be invoked
 before joining the thread.
 
-.. Note:: Once stop has been requested the queue will no longer accept further
-          work.
+.. note::
+   Once stop has been requested the queue will no longer accept further work.
 
 C++
 ===
 .. cpp:class:: pw::work_queue::WorkQueue
 
-  .. cpp:function:: Status PushWork(WorkItem work_item)
+   .. cpp:function:: Status PushWork(WorkItem work_item)
 
-     Enqueues a work_item for execution by the work queue thread.
+      Enqueues a work_item for execution by the work queue thread.
 
-     Returns:
+      Returns:
 
-     * **Ok** - Success, entry was enqueued for execution.
-     * **FailedPrecondition** - the work queue is shutting down, entries are no
-       longer permitted.
-     * **ResourceExhausted** - internal work queue is full, entry was not
-       enqueued.
+      * **Ok** - Success, entry was enqueued for execution.
+      * **FailedPrecondition** - the work queue is shutting down, entries are no
+        longer permitted.
+      * **ResourceExhausted** - internal work queue is full, entry was not
+        enqueued.
 
-  .. cpp:function:: void CheckPushWork(WorkItem work_item)
+   .. cpp:function:: void CheckPushWork(WorkItem work_item)
 
-     Queue work for execution. Crash if the work cannot be queued due to a
-     full queue or a stopped worker thread.
+      Queue work for execution. Crash if the work cannot be queued due to a
+      full queue or a stopped worker thread.
 
-     This call is recommended where possible since it saves error handling code
-     at the callsite; and in many practical cases, it is a bug if the work
-     queue is full (and so a crash is useful to detect the problem).
+      This call is recommended where possible since it saves error handling code
+      at the callsite; and in many practical cases, it is a bug if the work
+      queue is full (and so a crash is useful to detect the problem).
 
-     **Precondition:** The queue must not overflow, i.e. be full.
+      **Precondition:** The queue must not overflow, i.e. be full.
 
-     **Precondition:** The queue must not have been requested to stop, i.e. it
-     must not be in the process of shutting down.
+      **Precondition:** The queue must not have been requested to stop, i.e. it
+      must not be in the process of shutting down.
 
-  .. cpp:function:: void RequestStop()
+   .. cpp:function:: void RequestStop()
 
-     Locks the queue to prevent further work enqueing, finishes outstanding
-     work, then shuts down the worker thread.
+      Locks the queue to prevent further work enqueing, finishes outstanding
+      work, then shuts down the worker thread.
 
-     The WorkQueue cannot be resumed after stopping as the ThreadCore thread
-     returns and may be joined. It must be reconstructed for re-use after
-     the thread has been joined.
+      The WorkQueue cannot be resumed after stopping as the ThreadCore thread
+      returns and may be joined. It must be reconstructed for re-use after
+      the thread has been joined.
 
 Example
 -------
 
 .. code-block:: cpp
 
-  #include "pw_thread/detached_thread.h"
-  #include "pw_work_queue/work_queue.h"
+   #include "pw_thread/detached_thread.h"
+   #include "pw_work_queue/work_queue.h"
 
-  pw::work_queue::WorkQueueWithBuffer<10> work_queue;
+   pw::work_queue::WorkQueueWithBuffer<10> work_queue;
 
-  pw::thread::Options& WorkQueueThreadOptions();
-  void SomeLongRunningProcessing();
+   pw::thread::Options& WorkQueueThreadOptions();
+   void SomeLongRunningProcessing();
 
-  void SomeInterruptHandler() {
-    // Instead of executing the long running processing task in the interrupt,
-    // the work_queue executes it on the interrupt's behalf.
-    work_queue.CheckPushWork(SomeLongRunningProcessing);
-  }
+   void SomeInterruptHandler() {
+     // Instead of executing the long running processing task in the interrupt,
+     // the work_queue executes it on the interrupt's behalf.
+     work_queue.CheckPushWork(SomeLongRunningProcessing);
+   }
 
-  int main() {
-    // Start up the work_queue as a detached thread which runs forever.
-    pw::thread::DetachedThread(WorkQueueThreadOptions(), work_queue);
-  }
+   int main() {
+     // Start up the work_queue as a detached thread which runs forever.
+     pw::thread::DetachedThread(WorkQueueThreadOptions(), work_queue);
+   }
 
diff --git a/third_party/fuzztest/docs.rst b/third_party/fuzztest/docs.rst
index 854175e..4518421 100644
--- a/third_party/fuzztest/docs.rst
+++ b/third_party/fuzztest/docs.rst
@@ -93,8 +93,8 @@
 
 .. code-block:: sh
 
-  python pw_build/py/pw_build/generate_3p_gn.py \
-    -w third_party/fuzztest/src
+   python pw_build/py/pw_build/generate_3p_gn.py \
+     -w third_party/fuzztest/src
 
 .. DO NOT EDIT BELOW THIS LINE. Generated section.