ReadTheDocs improvements
diff --git a/README.rst b/README.rst
index 95f3cfa27fc..610ce38f290 100644
--- a/README.rst
+++ b/README.rst
@@ -1,6 +1,8 @@
 About the Let's Encrypt Client
 ==============================
 
+|build-status| |coverage| |docs|
+
 In short: getting and installing SSL/TLS certificates made easy (`watch demo video`_).
 
 The Let's Encrypt Client is a tool to automatically receive and install
@@ -25,10 +27,17 @@ All you need to do is:
 **Encrypt ALL the things!**
 
 
-.. image:: https://travis-ci.org/letsencrypt/lets-encrypt-preview.svg?branch=master
-    :target: https://travis-ci.org/letsencrypt/lets-encrypt-preview
-.. image:: https://coveralls.io/repos/letsencrypt/lets-encrypt-preview/badge.svg?branch=master
-    :target: https://coveralls.io/r/letsencrypt/lets-encrypt-preview
+.. |build-status| image:: https://travis-ci.org/letsencrypt/lets-encrypt-preview.svg?branch=master
+   :target: https://travis-ci.org/letsencrypt/lets-encrypt-preview
+   :alt: Travis CI status
+
+.. |coverage| image:: https://coveralls.io/repos/letsencrypt/lets-encrypt-preview/badge.svg?branch=master
+   :target: https://coveralls.io/r/letsencrypt/lets-encrypt-preview
+   :alt: Coverage status
+
+.. |docs| image:: https://readthedocs.org/projects/letsencrypt/badge/
+   :target: https://readthedocs.org/projects/letsencrypt/
+   :alt: Documentation status
 
 .. _watch demo video: https://www.youtube.com/watch?v=Gas_sSB-5SU
 
diff --git a/docs/conf.py b/docs/conf.py
index 018d2afedf0..2f25c9a7b3b 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -17,6 +17,14 @@
 import re
 import sys
 
+import mock
+
+
+# http://docs.readthedocs.org/en/latest/faq.html#i-get-import-errors-on-libraries-that-depend-on-c-modules
+# c.f. #262
+sys.modules.update(
+    (mod_name, mock.MagicMock()) for mod_name in ['augeas', 'M2Crypto'])
+
 here = os.path.abspath(os.path.dirname(__file__))
 
 # read version number (and other metadata) from package init
@@ -117,7 +125,15 @@
 
 # The theme to use for HTML and HTML Help pages.  See the documentation for
 # a list of builtin themes.
-html_theme = 'default'
+
+# http://docs.readthedocs.org/en/latest/theme.html#how-do-i-use-this-locally-and-on-read-the-docs
+# on_rtd is whether we are on readthedocs.org
+on_rtd = os.environ.get('READTHEDOCS', None) == 'True'
+if not on_rtd:  # only import and set the theme if we're building docs locally
+    import sphinx_rtd_theme
+    html_theme = 'sphinx_rtd_theme'
+    html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
+# otherwise, readthedocs.org uses their theme by default, so no need to specify it
 
 # Theme options are theme-specific and customize the look and feel of a theme
 # further.  For a list of options available for each theme, see the
diff --git a/docs/using.rst b/docs/using.rst
index d5b0086700f..2ebe1d078d2 100644
--- a/docs/using.rst
+++ b/docs/using.rst
@@ -53,7 +53,7 @@ The letsencrypt commandline tool has a builtin help:
 
 ::
 
-   letsencrypt --help
+   ./venv/bin/letsencrypt --help
 
 
 .. _augeas: http://augeas.net/
diff --git a/letsencrypt/client/interfaces.py b/letsencrypt/client/interfaces.py
index 04c7d35e783..efdb17c0a0e 100644
--- a/letsencrypt/client/interfaces.py
+++ b/letsencrypt/client/interfaces.py
@@ -30,9 +30,10 @@ def perform(chall_list):
 
         :param list chall_list: List of namedtuple types defined in
             :mod:`letsencrypt.client.challenge_util` (``DvsniChall``, etc.).
+
             - chall_list will never be empty
             - chall_list will only contain types found within
-                :func:`get_chall_pref`
+              :func:`get_chall_pref`
 
         :returns: ACME Challenge responses or if it cannot be completed then:
 
@@ -52,7 +53,7 @@ def cleanup(chall_list):
             :mod:`letsencrypt.client.challenge_util` (``DvsniChall``, etc.)
 
             - Only challenges given previously in the perform function will be
-            found in chall_list.
+              found in chall_list.
             - chall_list will never be empty
 
         """
diff --git a/readthedocs.org.requirements.txt b/readthedocs.org.requirements.txt
new file mode 100644
index 00000000000..27cccb0a6ae
--- /dev/null
+++ b/readthedocs.org.requirements.txt
@@ -0,0 +1,10 @@
+# readthedocs.org gives no way to change the install command to "pip
+# install -e .[docs]" (that would in turn install documentation
+# dependencies), but it allows to specify a requirements.txt file at
+# https://readthedocs.org/dashboard/letsencrypt/advanced/ (c.f. #259)
+
+# Although ReadTheDocs certainly doesn't need to install the project
+# in --editable mode (-e), just "pip install .[docs]" does not work as
+# expected and "pip install -e .[docs]" must be used instead
+
+-e .[docs]
diff --git a/setup.cfg b/setup.cfg
index 3369f299366..75b1ef1a8bd 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -2,7 +2,7 @@
 zip_ok = false
 
 [aliases]
-dev = develop easy_install letsencrypt[testing,dev]
+dev = develop easy_install letsencrypt[dev,docs,testing]
 
 [nosetests]
 nocapture=1
diff --git a/setup.py b/setup.py
index f2550446f7c..0568844d82d 100755
--- a/setup.py
+++ b/setup.py
@@ -40,8 +40,12 @@ def read_file(filename, encoding='utf8'):
 
 dev_extras = [
     'pylint>=1.4.0',  # upstream #248
+]
+
+docs_extras = [
     'repoze.sphinx.autointerface',
     'Sphinx',
+    'sphinx_rtd_theme',
 ]
 
 testing_extras = [
@@ -73,6 +77,7 @@ def read_file(filename, encoding='utf8'):
     test_suite='letsencrypt',
     extras_require={
         'dev': dev_extras,
+        'docs': docs_extras,
         'testing': testing_extras,
     },
     entry_points={
