Repository: M3t0r/tpl

Issue:
Document the presence of `_array_data` and `_scalar_data`
https://github.com/M3t0r/tpl/blob/feceeed182f1c2553b827d8f431f6be800204250/tpl/__init__.py#L101
This isn't mentioned anywhere. I think the cookbook of #3 could be a good place until we have a full fledged documentation.

Discussion:

Patch:
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
new file mode 100644
index 0000000..26c6f74
--- /dev/null
+++ b/CHANGELOG.rst
@@ -0,0 +1,91 @@
+Changelog
+=========
+
+Unreleased
+----------
+
+  - Added documentation with `ReadTheDocs <https://tpl.readthedocs.io/>`_
+    integration and a manpage. This includes a fix for `#8
+    <https://github.com/M3t0r/tpl/issues/8>`_.
+  - Added changelog with old releases.
+  - Include auxilliary files in the source distribution generated by
+    setuptools.
+  - Reformatted README.
+
+v0.8
+----
+*Released on 2018-10-27*
+
+  - Added support for Python 3.5.
+  - Added link to `Jinja2 template designer documentation
+    <http://jinja.pocoo.org/docs/templates/>`_ in ``--help`` output thanks to
+    `@loudambiance <https://github.com/loudambiance>`_.
+  - Changed a decent amount of building code with help from `@mre
+    <https://github.com/mre>`_.
+  - Added CI with `travis-ci <https://travis-ci.com/M3t0r/tpl>`_.
+  - Use Pipfile instead of requirements.txt for the development environment.
+  - Fixed ``-v`` option in Docker image.
+
+v0.7
+----
+*Released on 2018-07-17*
+
+  - Instead of simply updating only the top level dict we now merge
+    dictionaries on all levels.
+  - Added support for lists and scalar values a root level of data sources.
+  - Added automated builds for Dockerhub
+
+v0.6.2
+------
+*Released on 2018-07-16*
+
+  - First release to `PyPI <https://pypi.org/project/tpl/>`_.
+
+v0.6.1
+------
+*Released on 2018-07-16*
+
+  - Fix release target in Makefile.
+
+v0.6
+----
+*Released on 2018-07-16*
+
+  - Generated version numbers now adhere to PEP 440.
+
+v0.5
+----
+*Released on 2018-07-12*
+
+  - Added new CLI end-to-end test suit.
+  - Improved Docker image.
+  - Printing usage and help texts to ``STDERR`` instead of ``STDOUT``.
+
+v0.4
+----
+*Released on 2018-07-01*
+
+  - Improved ``--help`` message with option explanations.
+  - Added usage text to README.
+
+v0.3
+----
+*Released on 2018-07-01*
+
+  - Use a multistage Dockerfile.
+
+v0.2
+----
+*Released on 2018-06-29*
+
+  - Add Dockerfile together with
+    `Docker hub <https://hub.docker.com/r/m3t0r/tpl/>`_ integration.
+  - Forcefully end every render in a newline. Previously newlines at the end
+    were dropped by Jinja.
+  - Fixed installation not working.
+
+v0.1
+----
+*Released on 2018-06-29*
+
+Initial commit & release.
diff --git a/MANIFEST.in b/MANIFEST.in
new file mode 100644
index 0000000..61bb72e
--- /dev/null
+++ b/MANIFEST.in
@@ -0,0 +1,5 @@
+include Makefile LICENSE CHANGELOG.rst Pipfile Dockerfile
+
+graft tests
+graft docs
+
diff --git a/Makefile b/Makefile
index 758f771..1d31270 100644
--- a/Makefile
+++ b/Makefile
@@ -11,10 +11,20 @@ docker: zipapp Dockerfile
 	@echo " ==>" `tput setaf 2`Succesfully`tput sgr0` build `tput setaf 4`$@`tput sgr0`.
 
 .PHONY: wheel
-wheel:
+wheel: $(DistFolder)/tpl.1
 	python3 ./setup.py sdist bdist_wheel
 	@echo " ==>" `tput setaf 2`Succesfully`tput sgr0` build `tput setaf 4`$@`tput sgr0`.
 
+.PHONY: docs documentation
+docs documentation: $(DistFolder)/tpl.1 $(BuildFolder)
+	@echo " ==>" `tput setaf 3`Building`tput sgr0` HTML documentation for `tput setaf 4;./setup.py -V;tput sgr0`
+	sphinx-build -j auto -d $(BuildFolder)/sphinx -b html docs $(DistFolder)/docs
+
+$(DistFolder)/tpl.1: docs/manpage.rst
+	@# calling `./setup.py -V` makes sure that tpl.__version__ exists and docs/conf.py can import it
+	@echo " ==>" `tput setaf 3`Building`tput sgr0` manpage for `tput setaf 4;./setup.py -V;tput sgr0`
+	sphinx-build -d $(BuildFolder)/sphinx -b man -E docs $(DistFolder)
+
 .PHONY: test
 test: codestyle
 	pytest ./tests
@@ -27,7 +37,7 @@ codestyle:
 	-flake8 --ignore=F401,F811 --max-line-length=88 tests/ && echo " ==>" Codestyle is `tput setaf 2`conforming`tput sgr0`.
 
 .PHONY: all
-all: test zipapp # this is not all but the ones we recommend
+all: test zipapp documentation # this is not all but the ones we recommend
 
 .PHONY: check-releasable-git-state
 check-releasable-git-state:
diff --git a/Pipfile b/Pipfile
index 479f222..8874ed6 100644
--- a/Pipfile
+++ b/Pipfile
@@ -9,3 +9,4 @@ tpl = {editable = true, path = "."}
 [dev-packages]
 "flake8" = ">=3.3"
 pytest = ">=3.4"
+sphinx = "*"
diff --git a/Pipfile.lock b/Pipfile.lock
index 6df7663..ee7a28d 100644
--- a/Pipfile.lock
+++ b/Pipfile.lock
@@ -1,7 +1,7 @@
 {
     "_meta": {
         "hash": {
-            "sha256": "65e94a6d93c93786c9ec3cf395ff2251817869f950c22fed0e7987b544917189"
+            "sha256": "07307619242189f573dba28aba30b44cfa8089a08741b018320cef16650bac2e"
         },
         "pipfile-spec": 6,
         "requires": {},
@@ -23,9 +23,36 @@
         },
         "markupsafe": {
             "hashes": [
-                "sha256:a6be69091dac236ea9c6bc7d012beab42010fa914c459791d627dad4910eb665"
+                "sha256:048ef924c1623740e70204aa7143ec592504045ae4429b59c30054cb31e3c432",
+                "sha256:130f844e7f5bdd8e9f3f42e7102ef1d49b2e6fdf0d7526df3f87281a532d8c8b",
+                "sha256:19f637c2ac5ae9da8bfd98cef74d64b7e1bb8a63038a3505cd182c3fac5eb4d9",
+                "sha256:1b8a7a87ad1b92bd887568ce54b23565f3fd7018c4180136e1cf412b405a47af",
+                "sha256:1c25694ca680b6919de53a4bb3bdd0602beafc63ff001fea2f2fc16ec3a11834",
+                "sha256:1f19ef5d3908110e1e891deefb5586aae1b49a7440db952454b4e281b41620cd",
+                "sha256:1fa6058938190ebe8290e5cae6c351e14e7bb44505c4a7624555ce57fbbeba0d",
+                "sha256:31cbb1359e8c25f9f48e156e59e2eaad51cd5242c05ed18a8de6dbe85184e4b7",
+                "sha256:3e835d8841ae7863f64e40e19477f7eb398674da6a47f09871673742531e6f4b",
+                "sha256:4e97332c9ce444b0c2c38dd22ddc61c743eb208d916e4265a2a3b575bdccb1d3",
+                "sha256:525396ee324ee2da82919f2ee9c9e73b012f23e7640131dd1b53a90206a0f09c",
+                "sha256:52b07fbc32032c21ad4ab060fec137b76eb804c4b9a1c7c7dc562549306afad2",
+                "sha256:52ccb45e77a1085ec5461cde794e1aa037df79f473cbc69b974e73940655c8d7",
+                "sha256:5c3fbebd7de20ce93103cb3183b47671f2885307df4a17a0ad56a1dd51273d36",
+                "sha256:5e5851969aea17660e55f6a3be00037a25b96a9b44d2083651812c99d53b14d1",
+                "sha256:5edfa27b2d3eefa2210fb2f5d539fbed81722b49f083b2c6566455eb7422fd7e",
+                "sha256:7d263e5770efddf465a9e31b78362d84d015cc894ca2c131901a4445eaa61ee1",
+                "sha256:83381342bfc22b3c8c06f2dd93a505413888694302de25add756254beee8449c",
+                "sha256:857eebb2c1dc60e4219ec8e98dfa19553dae33608237e107db9c6078b1167856",
+                "sha256:98e439297f78fca3a6169fd330fbe88d78b3bb72f967ad9961bcac0d7fdd1550",
+                "sha256:bf54103892a83c64db58125b3f2a43df6d2cb2d28889f14c78519394feb41492",
+                "sha256:d9ac82be533394d341b41d78aca7ed0e0f4ba5a2231602e2f05aa87f25c51672",
+                "sha256:e982fe07ede9fada6ff6705af70514a52beb1b2c3d25d4e873e82114cf3c5401",
+                "sha256:edce2ea7f3dfc981c4ddc97add8a61381d9642dc3273737e756517cc03e84dd6",
+                "sha256:efdc45ef1afc238db84cb4963aa689c0408912a0239b0721cb172b4016eb31d6",
+                "sha256:f137c02498f8b935892d5c0172560d7ab54bc45039de8805075e19079c639a9c",
+                "sha256:f82e347a72f955b7017a39708a3667f106e6ad4d10b25f237396a7115d8ed5fd",
+                "sha256:fb7c206e01ad85ce57feeaaa0bf784b97fa3cad0d4a5737bc5295785f5c613a1"
             ],
-            "version": "==1.0"
+            "version": "==1.1.0"
         },
         "pyyaml": {
             "hashes": [
@@ -49,27 +76,117 @@
         }
     },
     "develop": {
+        "alabaster": {
+            "hashes": [
+                "sha256:446438bdcca0e05bd45ea2de1668c1d9b032e1a9154c2c259092d77031ddd359",
+                "sha256:a661d72d58e6ea8a57f7a86e37d86716863ee5e92788398526d58b26a4e4dc02"
+            ],
+            "version": "==0.7.12"
+        },
         "atomicwrites": {
             "hashes": [
-                "sha256:240831ea22da9ab882b551b31d4225591e5e447a68c5e188db5b89ca1d487585",
-                "sha256:a24da68318b08ac9c9c45029f4a10371ab5b20e4226738e150e6e7c571630ae6"
+                "sha256:0312ad34fcad8fac3704d441f7b317e50af620823353ec657a53e981f92920c0",
+                "sha256:ec9ae8adaae229e4f8446952d204a3e4b5fdd2d099f9be3aaf556120135fb3ee"
             ],
-            "version": "==1.1.5"
+            "version": "==1.2.1"
         },
         "attrs": {
             "hashes": [
-                "sha256:4b90b09eeeb9b88c35bc642cbac057e45a5fd85367b985bd2809c62b7b939265",
-                "sha256:e0d0eb91441a3b53dab4d9b743eafc1ac44476296a2053b6ca3af0b139faf87b"
+                "sha256:10cbf6e27dbce8c30807caf056c8eb50917e0eaafe86347671b57254006c3e69",
+                "sha256:ca4be454458f9dec299268d472aaa5a11f67a4ff70093396e1ceae9c76cf4bbb"
+            ],
+            "version": "==18.2.0"
+        },
+        "babel": {
+            "hashes": [
+                "sha256:6778d85147d5d85345c14a26aada5e478ab04e39b078b0745ee6870c2b5cf669",
+                "sha256:8cba50f48c529ca3fa18cf81fa9403be176d374ac4d60738b839122dfaaa3d23"
+            ],
+            "version": "==2.6.0"
+        },
+        "certifi": {
+            "hashes": [
+                "sha256:339dc09518b07e2fa7eda5450740925974815557727d6bd35d319c1524a04a4c",
+                "sha256:6d58c986d22b038c8c0df30d639f23a3e6d172a05c3583e766f4c0b785c0986a"
+            ],
+            "version": "==2018.10.15"
+        },
+        "chardet": {
+            "hashes": [
+                "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae",
+                "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"
+            ],
+            "version": "==3.0.4"
+        },
+        "docutils": {
+            "hashes": [
+                "sha256:02aec4bd92ab067f6ff27a38a38a41173bf01bed8f89157768c1573f53e474a6",
+                "sha256:51e64ef2ebfb29cae1faa133b3710143496eca21c530f3f71424d77687764274",
+                "sha256:7a4bd47eaf6596e1295ecb11361139febe29b084a87bf005bf899f9a42edc3c6"
             ],
-            "version": "==18.1.0"
+            "version": "==0.14"
         },
         "flake8": {
             "hashes": [
-                "sha256:7253265f7abd8b313e3892944044a365e3f4ac3fcdcfb4298f55ee9ddf188ba0",
-                "sha256:c7841163e2b576d435799169b78703ad6ac1bbb0f199994fc05f700b2a90ea37"
+                "sha256:6a35f5b8761f45c5513e3405f110a86bea57982c3b75b766ce7b65217abe1670",
+                "sha256:c01f8a3963b3571a8e6bd7a4063359aff90749e160778e03817cd9b71c9e07d2"
             ],
             "index": "pypi",
-            "version": "==3.5.0"
+            "version": "==3.6.0"
+        },
+        "idna": {
+            "hashes": [
+                "sha256:156a6814fb5ac1fc6850fb002e0852d56c0c8d2531923a51032d1b70760e186e",
+                "sha256:684a38a6f903c1d71d6d5fac066b58d7768af4de2b832e426ec79c30daa94a16"
+            ],
+            "version": "==2.7"
+        },
+        "imagesize": {
+            "hashes": [
+                "sha256:3f349de3eb99145973fefb7dbe38554414e5c30abd0c8e4b970a7c9d09f3a1d8",
+                "sha256:f3832918bc3c66617f92e35f5d70729187676313caa60c187eb0f28b8fe5e3b5"
+            ],
+            "version": "==1.1.0"
+        },
+        "jinja2": {
+            "hashes": [
+                "sha256:74c935a1b8bb9a3947c50a54766a969d4846290e1e788ea44c1392163723c3bd",
+                "sha256:f84be1bb0040caca4cea721fcbbbbd61f9be9464ca236387158b0feea01914a4"
+            ],
+            "version": "==2.10"
+        },
+        "markupsafe": {
+            "hashes": [
+                "sha256:048ef924c1623740e70204aa7143ec592504045ae4429b59c30054cb31e3c432",
+                "sha256:130f844e7f5bdd8e9f3f42e7102ef1d49b2e6fdf0d7526df3f87281a532d8c8b",
+                "sha256:19f637c2ac5ae9da8bfd98cef74d64b7e1bb8a63038a3505cd182c3fac5eb4d9",
+                "sha256:1b8a7a87ad1b92bd887568ce54b23565f3fd7018c4180136e1cf412b405a47af",
+                "sha256:1c25694ca680b6919de53a4bb3bdd0602beafc63ff001fea2f2fc16ec3a11834",
+                "sha256:1f19ef5d3908110e1e891deefb5586aae1b49a7440db952454b4e281b41620cd",
+                "sha256:1fa6058938190ebe8290e5cae6c351e14e7bb44505c4a7624555ce57fbbeba0d",
+                "sha256:31cbb1359e8c25f9f48e156e59e2eaad51cd5242c05ed18a8de6dbe85184e4b7",
+                "sha256:3e835d8841ae7863f64e40e19477f7eb398674da6a47f09871673742531e6f4b",
+                "sha256:4e97332c9ce444b0c2c38dd22ddc61c743eb208d916e4265a2a3b575bdccb1d3",
+                "sha256:525396ee324ee2da82919f2ee9c9e73b012f23e7640131dd1b53a90206a0f09c",
+                "sha256:52b07fbc32032c21ad4ab060fec137b76eb804c4b9a1c7c7dc562549306afad2",
+                "sha256:52ccb45e77a1085ec5461cde794e1aa037df79f473cbc69b974e73940655c8d7",
+                "sha256:5c3fbebd7de20ce93103cb3183b47671f2885307df4a17a0ad56a1dd51273d36",
+                "sha256:5e5851969aea17660e55f6a3be00037a25b96a9b44d2083651812c99d53b14d1",
+                "sha256:5edfa27b2d3eefa2210fb2f5d539fbed81722b49f083b2c6566455eb7422fd7e",
+                "sha256:7d263e5770efddf465a9e31b78362d84d015cc894ca2c131901a4445eaa61ee1",
+                "sha256:83381342bfc22b3c8c06f2dd93a505413888694302de25add756254beee8449c",
+                "sha256:857eebb2c1dc60e4219ec8e98dfa19553dae33608237e107db9c6078b1167856",
+                "sha256:98e439297f78fca3a6169fd330fbe88d78b3bb72f967ad9961bcac0d7fdd1550",
+                "sha256:bf54103892a83c64db58125b3f2a43df6d2cb2d28889f14c78519394feb41492",
+                "sha256:d9ac82be533394d341b41d78aca7ed0e0f4ba5a2231602e2f05aa87f25c51672",
+                "sha256:e982fe07ede9fada6ff6705af70514a52beb1b2c3d25d4e873e82114cf3c5401",
+                "sha256:edce2ea7f3dfc981c4ddc97add8a61381d9642dc3273737e756517cc03e84dd6",
+                "sha256:efdc45ef1afc238db84cb4963aa689c0408912a0239b0721cb172b4016eb31d6",
+                "sha256:f137c02498f8b935892d5c0172560d7ab54bc45039de8805075e19079c639a9c",
+                "sha256:f82e347a72f955b7017a39708a3667f106e6ad4d10b25f237396a7115d8ed5fd",
+                "sha256:fb7c206e01ad85ce57feeaaa0bf784b97fa3cad0d4a5737bc5295785f5c613a1"
+            ],
+            "version": "==1.1.0"
         },
         "mccabe": {
             "hashes": [
@@ -86,43 +203,76 @@
             ],
             "version": "==4.3.0"
         },
+        "packaging": {
+            "hashes": [
+                "sha256:0886227f54515e592aaa2e5a553332c73962917f2831f1b0f9b9f4380a4b9807",
+                "sha256:f95a1e147590f204328170981833854229bb2912ac3d5f89e2a8ccd2834800c9"
+            ],
+            "version": "==18.0"
+        },
         "pluggy": {
             "hashes": [
-                "sha256:6e3836e39f4d36ae72840833db137f7b7d35105079aee6ec4a62d9f80d594dd1",
-                "sha256:95eb8364a4708392bae89035f45341871286a333f749c3141c20573d2b3876e1"
+                "sha256:447ba94990e8014ee25ec853339faf7b0fc8050cdc3289d4d71f7f410fb90095",
+                "sha256:bde19360a8ec4dfd8a20dcb811780a30998101f078fc7ded6162f0076f50508f"
             ],
-            "markers": "python_version != '3.0.*' and python_version >= '2.7' and python_version != '3.2.*' and python_version != '3.1.*' and python_version != '3.3.*'",
-            "version": "==0.7.1"
+            "version": "==0.8.0"
         },
         "py": {
             "hashes": [
-                "sha256:3fd59af7435864e1a243790d322d763925431213b6b8529c6ca71081ace3bbf7",
-                "sha256:e31fb2767eb657cbde86c454f02e99cb846d3cd9d61b318525140214fdc0e98e"
+                "sha256:bf92637198836372b520efcba9e020c330123be8ce527e535d185ed4b6f45694",
+                "sha256:e76826342cefe3c3d5f7e8ee4316b80d1dd8a300781612ddbc765c17ba25a6c6"
             ],
-            "markers": "python_version != '3.0.*' and python_version >= '2.7' and python_version != '3.2.*' and python_version != '3.1.*' and python_version != '3.3.*'",
-            "version": "==1.5.4"
+            "version": "==1.7.0"
         },
         "pycodestyle": {
             "hashes": [
-                "sha256:682256a5b318149ca0d2a9185d365d8864a768a28db66a84a2ea946bcc426766",
-                "sha256:6c4245ade1edfad79c3446fadfc96b0de2759662dc29d07d80a6f27ad1ca6ba9"
+                "sha256:cbc619d09254895b0d12c2c691e237b2e91e9b2ecf5e84c26b35400f93dcfb83",
+                "sha256:cbfca99bd594a10f674d0cd97a3d802a1fdef635d4361e1a2658de47ed261e3a"
             ],
-            "version": "==2.3.1"
+            "version": "==2.4.0"
         },
         "pyflakes": {
             "hashes": [
-                "sha256:08bd6a50edf8cffa9fa09a463063c425ecaaf10d1eb0335a7e8b1401aef89e6f",
-                "sha256:8d616a382f243dbf19b54743f280b80198be0bca3a5396f1d2e1fca6223e8805"
+                "sha256:9a7662ec724d0120012f6e29d6248ae3727d821bba522a0e6b356eff19126a49",
+                "sha256:f661252913bc1dbe7fcfcbf0af0db3f42ab65aabd1a6ca68fe5d466bace94dae"
+            ],
+            "version": "==2.0.0"
+        },
+        "pygments": {
+            "hashes": [
+                "sha256:78f3f434bcc5d6ee09020f92ba487f95ba50f1e3ef83ae96b9d5ffa1bab25c5d",
+                "sha256:dbae1046def0efb574852fab9e90209b23f556367b5a320c0bcb871c77c3e8cc"
             ],
-            "version": "==1.6.0"
+            "version": "==2.2.0"
+        },
+        "pyparsing": {
+            "hashes": [
+                "sha256:40856e74d4987de5d01761a22d1621ae1c7f8774585acae358aa5c5936c6c90b",
+                "sha256:f353aab21fd474459d97b709e527b5571314ee5f067441dc9f88e33eecd96592"
+            ],
+            "version": "==2.3.0"
         },
         "pytest": {
             "hashes": [
-                "sha256:86a8dbf407e437351cef4dba46736e9c5a6e3c3ac71b2e942209748e76ff2086",
-                "sha256:e74466e97ac14582a8188ff4c53e6cc3810315f342f6096899332ae864c1d432"
+                "sha256:488c842647bbeb350029da10325cb40af0a9c7a2fdda45aeb1dda75b60048ffb",
+                "sha256:c055690dfefa744992f563e8c3a654089a6aa5b8092dded9b6fafbd70b2e45a7"
             ],
             "index": "pypi",
-            "version": "==3.7.1"
+            "version": "==4.0.0"
+        },
+        "pytz": {
+            "hashes": [
+                "sha256:31cb35c89bd7d333cd32c5f278fca91b523b0834369e757f4c5641ea252236ca",
+                "sha256:8e0f8568c118d3077b46be7d654cc8167fa916092e28320cde048e54bfc9f1e6"
+            ],
+            "version": "==2018.7"
+        },
+        "requests": {
+            "hashes": [
+                "sha256:65b3a120e4329e33c9889db89c80976c5272f56ea92d3e74da8a463992e3ff54",
+                "sha256:ea881206e59f41dbd0bd445437d792e43906703fff75ca8ff43ccdb11f33f263"
+            ],
+            "version": "==2.20.1"
         },
         "six": {
             "hashes": [
@@ -130,6 +280,35 @@
                 "sha256:832dc0e10feb1aa2c68dcc57dbb658f1c7e65b9b61af69048abc87a2db00a0eb"
             ],
             "version": "==1.11.0"
+        },
+        "snowballstemmer": {
+            "hashes": [
+                "sha256:919f26a68b2c17a7634da993d91339e288964f93c274f1343e3bbbe2096e1128",
+                "sha256:9f3bcd3c401c3e862ec0ebe6d2c069ebc012ce142cce209c098ccb5b09136e89"
+            ],
+            "version": "==1.2.1"
+        },
+        "sphinx": {
+            "hashes": [
+                "sha256:120732cbddb1b2364471c3d9f8bfd4b0c5b550862f99a65736c77f970b142aea",
+                "sha256:b348790776490894e0424101af9c8413f2a86831524bd55c5f379d3e3e12ca64"
+            ],
+            "index": "pypi",
+            "version": "==1.8.2"
+        },
+        "sphinxcontrib-websupport": {
+            "hashes": [
+                "sha256:68ca7ff70785cbe1e7bccc71a48b5b6d965d79ca50629606c7861a21b206d9dd",
+                "sha256:9de47f375baf1ea07cdb3436ff39d7a9c76042c10a769c52353ec46e4e8fc3b9"
+            ],
+            "version": "==1.1.0"
+        },
+        "urllib3": {
+            "hashes": [
+                "sha256:61bf29cada3fc2fbefad4fdf059ea4bd1b4a86d2b6d15e1c7c0b582b9752fe39",
+                "sha256:de9529817c93f27c8ccbfead6985011db27bd0ddfcdb2d86f3f663385c6a9c22"
+            ],
+            "version": "==1.24.1"
         }
     }
 }
diff --git a/README.md b/README.md
deleted file mode 100644
index 262e6bf..0000000
--- a/README.md
+++ /dev/null
@@ -1,61 +0,0 @@
-# `tpl`: Render templates with data from various sources
-
-<p><!-- badges --><a href="https://travis-ci.com/M3t0r/tpl"><img src="https://api.travis-ci.com/M3t0r/tpl.svg?branch=master" alt="travis-ci build badge"></a></p>
-
-You want to fill data into a template file?
-```shell
-tpl --yaml data.yaml template.file > rendered.file
-```
-
-You have everything already set up in your environment and now you just want to
-POST it somewhere?
-```shell
-tpl structure.json | curl -X POST -H "Content-Type: application/json" -d@- httpbin.org/anything
-```
-
-You want to fill in a template in your CD pipeline and have access to docker?
-```shell
-echo "My go-to editor is {{VISUAL}} on {{OS}}" \
-  | docker run --rm -i -e "VISUAL" -e "OS=$(uname)" m3t0r/tpl -
-```
-
-## Installation
-`make install` or `pip install tpl`
-
-## Input sources
-`tpl` supports multiple sources:
- * YAML files (`--yaml <file>`)
- * JSON files (`--json <file>`)
- * environment variables (`--environment`)
-
-You can specify multiple sources at once, but if a key is present in more than
-one then it's value will be taken from the latter source. This can be useful if
-you have default values that you want to always be present:
-```shell
-tpl \
-  --yaml defaults.yaml \
-  --json <(curl -H "Content-Type: application/json" now.httpbin.org) \
-  template.jinja2 > results.html
-```
-
-# Usage
-```
-Usage:
-  tpl [options] <template_file>
-  tpl --help
-  tpl --version
-
-
-tpl uses the Jinja2 templating engine to render it's output. You can find the
-documentation for template designers at:
-    http://jinja.pocoo.org/docs/latest/templates/
-
-If you provide multiple data sources they will be merged together. If a key is
-present in more than one source the value of the source that was specified
-last will be used. Nested objects will be merged with the same algorithm.
-
-Options:
-  -e, --environment    Use all environment variables as data
-  --json=<file>        Load JSON data from a file or STDIN
-  --yaml=<file>        Load YAML data from a file or STDIN
-```
diff --git a/README.rst b/README.rst
new file mode 100644
index 0000000..11706cf
--- /dev/null
+++ b/README.rst
@@ -0,0 +1,83 @@
+:program:`tpl`: render templates with data from various sources
+===============================================================
+
+.. highlight:: bash
+
+.. image:: https://api.travis-ci.com/M3t0r/tpl.svg?branch=master
+    :target: https://travis-ci.com/M3t0r/tpl
+    :alt: travis-ci build badge
+
+.. image:: https://img.shields.io/pypi/v/tpl.svg
+    :target: https://pypi.python.org/pypi/tpl/
+    :alt: 
+
+.. image:: https://readthedocs.org/projects/tpl/badge/
+    :target: https://readthedocs.org/projects/tpl/
+    :alt: Documentation Status
+
+You want to fill data into a template file? ::
+
+    tpl --yaml data.yaml template.file > rendered.file
+
+You have everything already set up in your environment and now you just want to
+POST it somewhere? ::
+
+    tpl structure.json \
+      | curl \
+          -X POST \
+          -H "Content-Type: application/json" \
+          -d@- \
+          httpbin.org/anything
+
+You want to fill in a template in your CD pipeline and have access to docker? ::
+
+    echo "My go-to editor is {{VISUAL}} on {{OS}}" \
+      | docker run --rm -i -e "VISUAL" -e "OS=$(uname)" M3t0r/tpl -
+
+Installation
+------------
+
+``pip install tpl``, ``docker pull M3t0r/tpl`` or ``make install`` 
+
+Input sources
+-------------
+
+:program:`tpl` supports multiple sources:
+ * YAML files (``--yaml <file>``)
+ * JSON files (``--json <file>``)
+ * environment variables (``--environment``)
+
+You can specify multiple sources at once, but if a key is present in more than
+one then it's value will be taken from the latter source. This can be useful if
+you have default values that you want to always be present::
+
+    tpl \
+      --yaml defaults.yaml \
+      --json <(curl -H "Content-Type: application/json" now.httpbin.org) \
+      template.jinja2 > results.html
+
+Usage
+-----
+.. highlight:: none
+
+::
+
+    Usage:
+      tpl [options] <template_file>
+      tpl --help
+      tpl --version
+    
+    
+    tpl uses the Jinja2 templating engine to render it's output. You can find the
+    documentation for template designers at:
+        http://jinja.pocoo.org/docs/latest/templates/
+    
+    If you provide multiple data sources they will be merged together. If a key is
+    present in more than one source the value of the source that was specified
+    last will be used. Nested objects will be merged with the same algorithm.
+    
+    Options:
+      -e, --environment    Use all environment variables as data
+      --json=<file>        Load JSON data from a file or STDIN
+      --yaml=<file>        Load YAML data from a file or STDIN
+
diff --git a/docs/api.rst b/docs/api.rst
new file mode 100644
index 0000000..9aa4672
--- /dev/null
+++ b/docs/api.rst
@@ -0,0 +1,6 @@
+Python API
+==========
+
+.. automodule:: tpl
+    :members:
+
diff --git a/docs/changelog.rst b/docs/changelog.rst
new file mode 100644
index 0000000..3df7f14
--- /dev/null
+++ b/docs/changelog.rst
@@ -0,0 +1,2 @@
+.. include:: ../CHANGELOG.rst
+
diff --git a/docs/conf.py b/docs/conf.py
new file mode 100644
index 0000000..56973e4
--- /dev/null
+++ b/docs/conf.py
@@ -0,0 +1,113 @@
+# -*- coding: utf-8 -*-
+#
+# Configuration file for the Sphinx documentation builder.
+#
+# This file does only contain a selection of the most common options. For a
+# full list see the documentation:
+# http://www.sphinx-doc.org/en/master/config
+
+# -- Path setup --------------------------------------------------------------
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+#
+# import os
+# import sys
+# sys.path.insert(0, os.path.abspath('.'))
+
+
+# -- Project information -----------------------------------------------------
+
+project = 'tpl'
+copyright = '2018, Simon Lutz Brüggen'
+author = 'Simon Lutz Brüggen'
+
+from tpl.__version__ import __version__ as tpl_release_string
+# The short X.Y version
+version, _, _ = tpl_release_string.partition("+")
+# The full version, including alpha/beta/rc tags
+release = tpl_release_string
+
+
+# -- General configuration ---------------------------------------------------
+
+extensions = [
+    'sphinx.ext.autodoc',
+    'sphinx.ext.doctest',
+    'sphinx.ext.viewcode',
+    'sphinx.ext.intersphinx',
+]
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['_templates']
+
+# The suffix(es) of source filenames.
+# You can specify multiple suffix as a list of string:
+#
+# source_suffix = ['.rst', '.md']
+source_suffix = '.rst'
+
+# The master toctree document.
+master_doc = 'index'
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+# This pattern also affects html_static_path and html_extra_path.
+exclude_patterns = ['dist', 'build', '_build', 'Thumbs.db', '.DS_Store']
+
+
+# -- Options for HTML output -------------------------------------------------
+
+# The theme to use for HTML and HTML Help pages.  See the documentation for
+# a list of builtin themes.
+#
+html_theme = 'alabaster'
+
+# 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
+# documentation.
+#
+# html_theme_options = {}
+
+# Custom sidebar templates, must be a dictionary that maps document names
+# to template names.
+#
+# The default sidebars (for documents that don't match any pattern) are
+# defined by theme itself.  Builtin themes are using these templates by
+# default: ``['localtoc.html', 'relations.html', 'sourcelink.html',
+# 'searchbox.html']``.
+#
+# html_sidebars = {}
+
+
+# -- Options for manual page output ------------------------------------------
+
+# One entry per manual page. List of tuples
+# (source start file, name, description, authors, manual section).
+man_pages = [
+    ("manpage", 'tpl', 'render templates with data from various sources',
+     [author], 1)
+]
+
+
+# -- Options for Epub output -------------------------------------------------
+
+# Bibliographic Dublin Core info.
+epub_title = project
+
+# The unique identifier of the text. This can be a ISBN number
+
+#
+# epub_uid = ''
+
+# A list of files that should not be packed into the epub file.
+epub_exclude_files = ['search.html']
+
+
+# -- Extension configuration -------------------------------------------------
+intersphinx_mapping = {
+    'python': ('https://docs.python.org/3', None),
+    'jinja2': ('http://jinja.pocoo.org/docs/', None),
+}
+
diff --git a/docs/index.rst b/docs/index.rst
new file mode 100644
index 0000000..6d47bdd
--- /dev/null
+++ b/docs/index.rst
@@ -0,0 +1,22 @@
+.. include:: ../README.rst
+
+Documentation contents
+======================
+
+.. toctree::
+    :maxdepth: 2
+
+    manpage
+    cookbook
+
+Although :program:`tpl` is primarily developed as a CLI program there is some
+documentation of it's internals in the :doc:`Python API <api>` section.
+
+
+.. toctree::
+    :maxdepth: 2
+
+    api
+    license
+    changelog
+
diff --git a/docs/license.rst b/docs/license.rst
new file mode 100644
index 0000000..f6fc0af
--- /dev/null
+++ b/docs/license.rst
@@ -0,0 +1,15 @@
+:tocdepth: 1
+
+License
+=======
+
+:program:`tpl` is licensed under the `MIT license
+<https://choosealicense.com/licenses/mit/>`_. The license text from the
+``LICENSE`` file is repeated below.
+
+MIT license text
+----------------
+
+.. literalinclude:: ../LICENSE
+    :language: none
+
diff --git a/docs/manpage.rst b/docs/manpage.rst
new file mode 100644
index 0000000..ce64216
--- /dev/null
+++ b/docs/manpage.rst
@@ -0,0 +1,123 @@
+.. _tpl:
+
+:program:`tpl`: render templates with data from various sources
+===============================================================
+
+Synopsis
+--------
+
+.. program:: tpl
+
+| :program:`tpl` [:ref:`options <options>`] <:option:`template_file`> [:option:`output_file`]
+| :program:`tpl` :option:`-h` | :option:`--help`
+| :program:`tpl` :option:`-v` | :option:`--version`
+
+
+Description
+-----------
+
+:program:`tpl` renders a `Jinja2 <https://palletsprojects.com/p/jinja/>`_
+template file with data aggregated from one or more data sources specified via
+options and writes the result to :option:`output_file`. It is meant to be
+easily composable with other unix tools like :program:`xargs`, :program:`curl`,
+and :program:`jq`.
+
+.. option:: template_file
+
+    The template file that will be rendered. A :option:`template_file` of
+    "``-``" stands for ``STDIN``.
+
+.. option:: output_file
+
+    The file that the rendered template will be written to. If an error occurs
+    during templating the output might end up with incomplete and broken data.
+    When a file with the same name already exists it will be overwritten
+    without notice. If ommitted this argument defaults to "``-``" which stands
+    for ``STDOUT``.
+
+
+.. _options:
+
+Options
+-------
+
+The order of data source options is important. See the :ref:`data-merging`
+section for more information.
+
+.. option:: -h, --help
+
+    Print a help message to ``STDERR`` and exit successfully.
+
+.. option:: -v, --version
+
+    Write the version number to ``STDOUT`` and exit successfully.
+
+.. option:: -e, --environment
+
+    Load environmant variables as key-value pairs into the context. This allows
+    you to access, for example, `$PATH` with ``{{ PATH }}``.
+
+    If no other data source option was specified this option is used by
+    default. Templates can only access the environment if no other data sources
+    were specified or this flag is used. This is to prohibit leaking of secrets
+    from the environment.
+
+.. option:: --json <file>
+
+    Load data from a JSON file into the context. Unlike :program:`jq`,
+    :program:`tpl` does not support multiple JSON objects separated by
+    whitespaces. Internally this uses Python's :py:func:`json.load`.
+
+.. option:: --yaml <file>
+
+    Load data from a YAML file into the context. The YAML file can only contain
+    one document. If the parser encounters a second document :program:`tpl`
+    will abort with an error. This data source uses the
+    `PyYAML library <https://pyyaml.org/wiki/PyYAMLDocumentation>`_.
+
+
+.. _data-merging:
+
+Data Merging
+------------
+
+If you provide multiple data sources they will be merged together to provide a
+context for the Jinja2 engine. If a key is present in more than one source the
+value of the source that was specified last will be used. Nested objects will
+be merged with the same algorithm.
+
+.. only:: html
+
+    See :py:meth:`tpl.merge_data` and it's source code for the algorithm.
+
+Special treatment is given to root objects of every data source when merging:
+If the root object is a list, it's elements will be added to the end of
+``_array_data``. If the root object is a a scalar value, like a string,
+boolean, or number, it's value will be stored in ``_scalar_data``. When one of
+these special behaviours is triggered the already assembled context is not
+cleared of previously defined key-value pairs:
+
+.. code-block:: bash
+
+    $ tpl \
+    >     --json <(echo '"the answer"') \
+    >     --json <(echo '{"foo":"bar"}') \
+    >     --json <(echo "42") \
+    >     <(echo 'scalar: {{ _scalar_data }}, foo: {{ foo }}')
+    scalar: 42, foo: bar
+    # and not scalar: 42, foo:
+
+.. only:: html
+
+    This behaviour is only applied to values at the root:
+
+    .. code-block:: bash
+
+        $ tpl \
+        >     --json <(echo '{"spam":"egg"}') \
+        >     --json <(echo '{"spam":{"sub":"marine"}}') \
+        >     --json <(echo '{"spam":"ham"}') \
+        >     <(echo '{{ spam }}')
+        ham
+        # and not {'sub': 'marine', '_scalar_data': 'ham'}
+
diff --git a/setup.py b/setup.py
index 660b0a3..a3fa179 100755
--- a/setup.py
+++ b/setup.py
@@ -5,7 +5,7 @@ from os import popen
 from setuptools import setup
 
 
-with open("./README.md") as readme:
+with open("./README.rst") as readme:
     readme_text = readme.read()
 
 with popen(
@@ -31,7 +31,6 @@ setup(
     description="Render templates with data from various sources",
     url="https://github.com/m3t0r/tpl",
     long_description=readme_text,
-    long_description_content_type="text/markdown",
     python_requires=">3.5",
     install_requires=["pyyaml>=3.13", "jinja2>=2.10"],
     entry_points={


Test patch:
diff --git a/tests/test_interface.py b/tests/test_interface.py
index 04a2dab..0d8f9c8 100644
--- a/tests/test_interface.py
+++ b/tests/test_interface.py
@@ -4,9 +4,13 @@ import unittest.mock
 import tpl
 
 
+def indent(text, prefix):
+    return "\n".join( (prefix + line for line in text.splitlines()) )
+
+
 def test_current_help_in_readme(capsys):
     with unittest.mock.patch("jinja2.__version__", "latest"):
         tpl.print_help()
     output = capsys.readouterr()
-    with open("./README.md", "r") as readme:
-        assert output.err in readme.read()
+    with open("./README.rst", "r") as readme:
+        assert indent(output.err, " "*4) in readme.read()