Expand docs for a few modules

- Add missing README.md for a few modules.
- Start or expand docs.rst.

Change-Id: Ic13c5f71f02259205ba990c93e0403d43f7b44b1
diff --git a/docs/BUILD.gn b/docs/BUILD.gn
index 742314d..70eee10 100644
--- a/docs/BUILD.gn
+++ b/docs/BUILD.gn
@@ -36,6 +36,9 @@
     "$dir_pw_dumb_io_baremetal_stm32f429:docs",
     "$dir_pw_dumb_io_stdio:docs",
     "$dir_pw_preprocessor:docs",
+    "$dir_pw_presubmit:docs",
+    "$dir_pw_span:docs",
+    "$dir_pw_status:docs",
     "$dir_pw_string:docs",
     "$dir_pw_test_server:docs",
   ]
diff --git a/docs/modules.rst b/docs/modules.rst
index 09f69ac..4bf4bc1 100644
--- a/docs/modules.rst
+++ b/docs/modules.rst
@@ -11,5 +11,8 @@
   pw_dumb_io_baremetal_stm32f429/docs
   pw_dumb_io_stdio/docs
   pw_preprocessor/docs
+  pw_presubmit/docs
+  pw_span/docs
+  pw_status/docs
   pw_string/docs
   pw_test_server/docs
diff --git a/modules.gni b/modules.gni
index 16c6a2e..76d5de2 100644
--- a/modules.gni
+++ b/modules.gni
@@ -30,6 +30,7 @@
     "$dir_pigweed/pw_dumb_io_baremetal_stm32f429"
 dir_pw_dumb_io_stdio = "$dir_pigweed/pw_dumb_io_stdio"
 dir_pw_preprocessor = "$dir_pigweed/pw_preprocessor"
+dir_pw_presubmit = "$dir_pigweed/pw_presubmit"
 dir_pw_span = "$dir_pigweed/pw_span"
 dir_pw_status = "$dir_pigweed/pw_status"
 dir_pw_string = "$dir_pigweed/pw_string"
diff --git a/pw_preprocessor/docs.rst b/pw_preprocessor/docs.rst
index 048abb3..ae08b13 100644
--- a/pw_preprocessor/docs.rst
+++ b/pw_preprocessor/docs.rst
@@ -1,4 +1,4 @@
-.. _chapter-preprocessor:
+.. _chapter-pw-preprocessor:
 
 .. default-domain:: cpp
 
@@ -13,10 +13,6 @@
 =============
 C and C++
 
-Dependencies
-============
-This module has no dependencies.
-
 Headers
 =======
 The preprocessor module provides several headers.
diff --git a/pw_presubmit/BUILD.gn b/pw_presubmit/BUILD.gn
new file mode 100644
index 0000000..9eed4a2
--- /dev/null
+++ b/pw_presubmit/BUILD.gn
@@ -0,0 +1,21 @@
+# Copyright 2019 The Pigweed Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may not
+# use this file except in compliance with the License. You may obtain a copy of
+# the License at
+#
+#     https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations under
+# the License.
+
+import("$dir_pw_docgen/docs.gni")
+
+pw_doc_group("docs") {
+  sources = [
+    "docs.rst",
+  ]
+}
diff --git a/pw_presubmit/README.md b/pw_presubmit/README.md
new file mode 100644
index 0000000..60bde53
--- /dev/null
+++ b/pw_presubmit/README.md
@@ -0,0 +1 @@
+# pw\_presubmit: Tools for running presubmit checks
diff --git a/pw_presubmit/docs.rst b/pw_presubmit/docs.rst
new file mode 100644
index 0000000..01389b3
--- /dev/null
+++ b/pw_presubmit/docs.rst
@@ -0,0 +1,83 @@
+.. _chapter-pw-presubmit:
+
+.. default-domain:: cpp
+
+.. highlight:: sh
+
+------------
+pw_presubmit
+------------
+The presubmit module provides Python tools for running presubmit checks and
+checking and fixing code format. It also includes the presubmit check script for
+the Pigweed repository, ``pigweed_presubmit.py``.
+
+Compatibility
+=============
+Python 3
+
+pw_presubmit Python package
+===========================
+
+Presubmit tools
+---------------
+A presubmit check is defined as a function or other callable. The function may
+take either no arguments or a list of the paths on which to run. Presubmit
+checks communicate failure by raising any exception.
+
+For example, either of these functions may be used as presubmit checks:
+
+.. code-block:: python
+
+  @pw_presubmit.filter_paths(endswith='.py')
+  def file_contains_ni(paths):
+      for path in paths:
+          with open(path) as file:
+              contents = file.read()
+              if 'ni' not in contents and 'nee' not in contents:
+                  raise PresumitFailure('Files must say "ni"!', path=path)
+
+  def run_the_build():
+      subprocess.run(['make', 'release'], check=True)
+
+Presubmit checks are provided to the ``parse_args_and_run_presubmit`` or
+``run_presubmit`` function as a list. For example,
+
+.. code-block:: python
+
+  PRESUBMIT_CHECKS = [file_contains_ni, run_the_build]
+  sys.exit(0 if parse_args_and_run_presubmit(PRESUBMIT_CHECKS) else 1)
+
+Presubmit checks that accept a list of paths may use the ``filter_paths``
+decorator to automatically filter the paths list for file types they care about.
+
+Members
+^^^^^^^
+.. autofunction:: pw_presubmit.run_presubmit
+
+.. autofunction:: pw_presubmit.parse_args_and_run_presubmit
+
+.. autodecorator:: pw_presubmit.filter_paths
+
+.. autofunction:: pw_presubmit.call
+
+.. autoexception:: pw_presubmit.PresubmitFailure
+
+Presubmit checks
+----------------
+The pw_presubmit package includes presubmit checks that can be used with any
+project. These checks include:
+
+* Check code format of several languages including C, C++, and Python
+* Initialize a Python environment
+* Run all Python tests
+* Run pylint
+* Ensure source files are included in the GN and Bazel builds
+* Build and run all tests with GN
+* Build and run all tests with Bazel
+* Ensure all header files contain ``#pragma once``
+
+pw_presubmit.format_code
+------------------------
+The ``format_code`` submodule formats supported source files using external code
+format tools. The file ``format_code.py`` can be invoked directly from the
+command line or from ``pw`` as ``pw format``.
diff --git a/pw_presubmit/py/pw_presubmit/tools.py b/pw_presubmit/py/pw_presubmit/tools.py
index 0e1233b..d3ab723 100644
--- a/pw_presubmit/py/pw_presubmit/tools.py
+++ b/pw_presubmit/py/pw_presubmit/tools.py
@@ -13,18 +13,19 @@
 # the License.
 """Tools for running presubmit checks in a Git repository.
 
-A presubmit checks are defined as a function or other callable. The function may
+Presubmit checks are defined as a function or other callable. The function may
 take either no arguments or a list of the paths on which to run. Presubmit
 checks communicate failure by raising any exception.
 
 For example, either of these functions may be used as presubmit checks:
 
+  @pw_presubmit.filter_paths(endswith='.py')
   def file_contains_ni(paths):
       for path in paths:
           with open(path) as file:
-            contents = file.read()
-            if 'ni' not in contents and 'nee' not in contents:
-              raise PresumitFailure('Files must say "ni"!', path=path)
+              contents = file.read()
+              if 'ni' not in contents and 'nee' not in contents:
+                  raise PresumitFailure('Files must say "ni"!', path=path)
 
   def run_the_build():
       subprocess.run(['make', 'release'], check=True)
@@ -543,7 +544,7 @@
 
 @filter_paths(endswith='.h')
 def pragma_once(paths: Iterable[str]) -> None:
-    """Checks that all header files contain '#pragma once'."""
+    """Presubmit check that ensures all header files contain '#pragma once'."""
 
     for path in paths:
         with open(path) as file:
diff --git a/pw_span/BUILD.gn b/pw_span/BUILD.gn
index e28e253..52296d9 100644
--- a/pw_span/BUILD.gn
+++ b/pw_span/BUILD.gn
@@ -12,6 +12,7 @@
 # License for the specific language governing permissions and limitations under
 # the License.
 
+import("$dir_pw_docgen/docs.gni")
 import("$dir_pw_unit_test/test.gni")
 
 config("default_config") {
@@ -41,3 +42,9 @@
     "span_test.cc",
   ]
 }
+
+pw_doc_group("docs") {
+  sources = [
+    "docs.rst",
+  ]
+}
diff --git a/pw_span/README.md b/pw_span/README.md
new file mode 100644
index 0000000..23f2c5a
--- /dev/null
+++ b/pw_span/README.md
@@ -0,0 +1 @@
+# pw\_span: Stand-in for C++20's std::span
diff --git a/pw_span/docs.rst b/pw_span/docs.rst
new file mode 100644
index 0000000..5074958
--- /dev/null
+++ b/pw_span/docs.rst
@@ -0,0 +1,62 @@
+.. _chapter-pw-span:
+
+.. default-domain:: cpp
+
+.. highlight:: sh
+
+-------
+pw_span
+-------
+The pw_span module provides an implementation of C++20's
+`std::span <https://en.cppreference.com/w/cpp/container/span>`_, which is a
+non-owning view of an array of values. The intent is for ``pw::span``'s
+interface to exactly match ``std::span``.
+
+``pw::span`` is a convenient abstraction that wraps a pointer and a size.
+``pw::span`` is especially useful in APIs. Spans support implicit conversions
+from C arrays, ``std::array``, or any STL-style constainer, such as
+``std::string_view``.
+
+Functions operating on an array of bytes typically accept pointer and size
+arguments:
+
+.. code-block:: cpp
+
+  bool ProcessBuffer(char* buffer, size_t buffer_size);
+
+  bool DoStuff() {
+    ProcessBuffer(c_array, sizeof(c_array));
+    ProcessBuffer(array_object.data(), array_object.size());
+    ProcessBuffer(data_pointer, data_size);
+  }
+
+Pointer and size arguments can be replaced with a ``pw::span``:
+
+.. code-block:: cpp
+
+  // With pw::span, the buffer is passed as a single argument.
+  bool ProcessBuffer(const pw::span<uint8_t>& buffer);
+
+  bool DoStuff() {
+    ProcessBuffer(c_array);
+    ProcessBuffer(array_object);
+    ProcessBuffer(span(data_pointer, data_size));
+  }
+
+.. tip::
+  Use ``pw::span<std::byte>`` or ``pw::span<const std::bytes>`` to represent
+  spans of binary data. The ``pw::as_bytes`` or ``pw::as_writeable_bytes``
+  functions make converting to byte arrays very simple.
+
+  .. code-block:: cpp
+
+    void ProcessData(pw::span<const std::byte> data);
+
+    void DoStuff() {
+      std::array<AnyType, 7> data = { ... };
+      ProcessData(pw::as_bytes(data));
+    }
+
+Compatibility
+=============
+C++17
diff --git a/pw_status/BUILD.gn b/pw_status/BUILD.gn
index 6757fd8..c4e8a98 100644
--- a/pw_status/BUILD.gn
+++ b/pw_status/BUILD.gn
@@ -12,6 +12,7 @@
 # License for the specific language governing permissions and limitations under
 # the License.
 
+import("$dir_pw_docgen/docs.gni")
 import("$dir_pw_unit_test/test.gni")
 
 config("default_config") {
@@ -54,3 +55,9 @@
     "status_with_size_test.cc",
   ]
 }
+
+pw_doc_group("docs") {
+  sources = [
+    "docs.rst",
+  ]
+}
diff --git a/pw_status/README.md b/pw_status/README.md
index 2f3c97a..88b8646 100644
--- a/pw_status/README.md
+++ b/pw_status/README.md
@@ -1 +1 @@
-# pw\_status: Pigweed error codes
+# pw\_status: Pigweed status codes
diff --git a/pw_status/docs.rst b/pw_status/docs.rst
new file mode 100644
index 0000000..faee13b
--- /dev/null
+++ b/pw_status/docs.rst
@@ -0,0 +1,21 @@
+.. _chapter-pw-status:
+
+.. default-domain:: cpp
+
+.. highlight:: sh
+
+---------
+pw_status
+---------
+``pw::Status`` (``pw_status/status.h``) is a simple, zero-overhead status
+object. It uses Google's standard status codes, which are also used by projects
+such as `gRPC <https://github.com/grpc/grpc/blob/master/doc/statuscodes.md>`_.
+
+``pw::StatusWithSize`` (``pw_status/status_with_size.h``) is a convenient,
+efficent class for reporting a status along with an unsigned integer value.
+
+The classes in pw_status are used extensively by other Pigweed modules.
+
+Compatibility
+=============
+C++11
diff --git a/pw_string/README.md b/pw_string/README.md
new file mode 100644
index 0000000..2cfee8e
--- /dev/null
+++ b/pw_string/README.md
@@ -0,0 +1 @@
+# pw\_string: Utilities for building strings
diff --git a/pw_string/docs.rst b/pw_string/docs.rst
index 4c78276..a47b08f 100644
--- a/pw_string/docs.rst
+++ b/pw_string/docs.rst
@@ -1,4 +1,4 @@
-.. _chapter-string:
+.. _chapter-pw-string:
 
 .. default-domain:: cpp
 
@@ -7,14 +7,16 @@
 ---------
 pw_string
 ---------
-The string module provides utilities for working with strings.
+The string module provides efficient utilities for safely working with strings.
+The pw_string functions and classes always null-terminate strings and never
+overrun buffers. They do not allocate their own memory.
 
-Requirements
+Compatibility
 =============
 C++17
 
-Module Dependencies
--------------------
+Dependencies
+============
 * pw_preprocessor
 * pw_status
 * pw_span
@@ -39,8 +41,8 @@
 pw::StringBuilder
 -----------------
 StringBuilder facilitates building formatted strings in a fixed-size buffer.
-StringBuilder is safe, flexible, and results in much smaller code size than
-using std::ostringstream. However, applications sensitive to code size should
+It is designed to give the flexibility of std::string and std::ostringstream,
+but with a small footprint. However, applications sensitive to code size should
 use StringBuilder with care.
 
 Size report: replacing snprintf with pw::StringBuilder