aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStanislaw Klekot <[email protected]>2017-10-30 20:39:07 +0100
committerLoïc Hoguin <[email protected]>2018-01-24 13:23:15 +0100
commitad88794506a0ccf0671dd9b909890e0a80b346cc (patch)
treebd407f6dbf3f3ac82cc82d0f485ca9938c6774cb
parentf545564473f0f92cc5b266616b289cf6266e9e28 (diff)
downloaderlang.mk-ad88794506a0ccf0671dd9b909890e0a80b346cc.tar.gz
erlang.mk-ad88794506a0ccf0671dd9b909890e0a80b346cc.tar.bz2
erlang.mk-ad88794506a0ccf0671dd9b909890e0a80b346cc.zip
Add support for Sphinx documentation builder
-rw-r--r--build.config1
-rw-r--r--doc/src/guide/book.asciidoc2
-rw-r--r--doc/src/guide/sphinx.asciidoc134
-rw-r--r--plugins/sphinx.mk62
-rw-r--r--test/plugin_sphinx.mk180
5 files changed, 379 insertions, 0 deletions
diff --git a/build.config b/build.config
index ae146ac..154a7ea 100644
--- a/build.config
+++ b/build.config
@@ -34,6 +34,7 @@ plugins/eunit
plugins/proper
plugins/relx
plugins/shell
+plugins/sphinx
plugins/syntastic
plugins/triq
plugins/xref
diff --git a/doc/src/guide/book.asciidoc b/doc/src/guide/book.asciidoc
index 571d06d..085c147 100644
--- a/doc/src/guide/book.asciidoc
+++ b/doc/src/guide/book.asciidoc
@@ -41,6 +41,8 @@ include::asciidoc.asciidoc[Asciidoc documentation]
include::edoc.asciidoc[EDoc comments]
+include::sphinx.asciidoc[Sphinx documentation]
+
[[tests]]
= Tests
diff --git a/doc/src/guide/sphinx.asciidoc b/doc/src/guide/sphinx.asciidoc
new file mode 100644
index 0000000..a20dee5
--- /dev/null
+++ b/doc/src/guide/sphinx.asciidoc
@@ -0,0 +1,134 @@
+[[sphinx]]
+== Sphinx documentation
+
+Erlang.mk includes targets for running
+http://www.sphinx-doc.org/[Sphinx documentation generator], which can produce
+documentation in various formats, like HTML, man pages, Texinfo, LaTeX, and
+others.
+
+=== Writing Sphinx documentation
+
+Sphinx generates documentation form a set of
+http://www.sphinx-doc.org/en/stable/rest.html[reST] documents. There is
+a http://www.sphinx-doc.org/en/stable/tutorial.html[quick start guide] on
+Sphinx' website. For Erlang.mk, we'll set up a minimal environment instead.
+
+=== Basic setup
+
+By default, Erlang.mk expects Sphinx documentation to be placed in 'doc'
+directory, with 'doc/conf.py' config file in particular. The file contains
+information about the project, among the other things.
+
+A minimal 'doc/conf.py' will look similar to this:
+
+[source,python]
+----
+project = 'My Project'
+version = '0.0'
+release = '0.0.1'
+master_doc = 'index'
+source_suffix = '.rst'
+----
+
+It points to a 'doc/index.rst' document. A simple skeleton includes a table of
+contents for all documentation, and links to generated index of terms and
+a search page:
+
+[literal]
+----
+My Project
+==========
+
+Contents:
+
+.. toctree::
+ :maxdepth: 2
+
+ other_page
+
+Indices and tables
+==================
+
+* :ref:`genindex`
+* :ref:`search`
+----
+
+The skeleton above has a link to one other page, 'doc/other_page.rst'. Simple
+header with some text will do for now:
+
+[literal]
+----
+Other Page
+==========
+
+Lorem ipsum dolor sit amet...
+----
+
+The files above are enough to build HTML documentation to 'html' directory.
+
+[source,bash]
+$ make docs # all the docs, including EDoc and AsciiDoc if applicable
+$ make sphinx # Sphinx docs specifically
+
+=== Erlang.mk configuration
+
+Default Erlang.mk settings are equivalent to adding to project's makefile
+following lines:
+
+[source,make]
+SPHINX_FORMATS = html
+SPHINX_SOURCE = doc
+
+To change the location of Sphinx sources, you need to set `$(SPHINX_SOURCE)`
+variable. 'conf.py' file should also be placed in that directory, unless you
+specify `$(SPHINX_CONFDIR)`.
+
+Variable `$(SPHINX_OPTS)` allows to provide options to `sphinx-build`, which
+is particularly useful for `-D name=value` options. You can even forego
+'doc/conf.py' file, using `-D name=value` in combination with `-C` option,
+though you will need to manually call `make sphinx` or add `sphinx` target to
+dependencies of `docs`.
+
+`$(SPHINX_FORMATS)` variable lists formats to generate. By default only HTML
+is generated, but it can also include man pages or LaTeX document for building
+PDF. See
+http://www.sphinx-doc.org/en/stable/invocation.html#cmdoption-sphinx-build-b[description of `-b` option]
+for `sphinx-build` for list of known formats.
+
+Formats are by default generated to a directory called after the format
+('html' for HTML, 'man' for man pages, and so on). To change this behaviour
+for specific format, you can set `$(sphinx_$(format)_output)` variable, e.g.
+`$(sphinx_html_output)` for 'html' or `$(sphinx_man_output)` for 'man'.
+There are also `$(sphinx_$(format)_opts)` variables for setting `sphinx-build`
+options for a single format only.
+
+=== Generating man pages
+
+To generate man pages, you need to include `man` in `$(SPHINX_FORMATS)` in
+your makefile and define `man_pages` option in 'doc/conf.py':
+
+[source,python]
+----
+man_pages = [
+ ('doc_name', 'page_name', 'Manpage Title', ['Page Author'], 1),
+]
+----
+
+As http://www.sphinx-doc.org/en/stable/config.html#options-for-manual-page-output[Sphinx documentation]
+says, the structure is following:
+
+* 'doc_name' is the path to man page's source (relative `$(SPHINX_SOURCE)`),
+ without the '.rst' suffix
+* 'page_name' is the name of resulting man page, which will be used as a base
+ for output file name and will be included in generated man page
+* 'Manpage Title' is a short, one-line description, which will be included in
+ generated man page on a position that's used by `apropos` command
+* 'Page Author' (or more of them) will be included in autogenerated 'AUTHOR'
+ section, and leaving this field empty disables generating 'AUTHOR' section
+* '1' is the number of section of the man page
+
+With the above configuration (and Erlang.mk defaults), 'doc/doc_name.rst' will
+be used to generate 'man/page_name.1'.
+
+NOTE: You probably want to include a link to the man page in other
+documentation, possibly in 'doc/index.rst'.
diff --git a/plugins/sphinx.mk b/plugins/sphinx.mk
new file mode 100644
index 0000000..4718247
--- /dev/null
+++ b/plugins/sphinx.mk
@@ -0,0 +1,62 @@
+# Copyright 2017, Stanislaw Klekot <[email protected]>
+# This file is part of erlang.mk and subject to the terms of the ISC License.
+
+.PHONY: distclean-sphinx sphinx
+
+# Configuration.
+
+SPHINX_BUILD ?= sphinx-build
+SPHINX_SOURCE ?= doc
+SPHINX_CONFDIR ?=
+SPHINX_FORMATS ?= html
+SPHINX_DOCTREES ?= $(ERLANG_MK_TMP)/sphinx.doctrees
+SPHINX_OPTS ?=
+
+#sphinx_html_opts =
+#sphinx_html_output = html
+#sphinx_man_opts =
+#sphinx_man_output = man
+#sphinx_latex_opts =
+#sphinx_latex_output = latex
+
+# Helpers.
+
+sphinx_build_0 = @echo " SPHINX" $1; $(SPHINX_BUILD) -N -q
+sphinx_build_1 = $(SPHINX_BUILD) -N
+sphinx_build_2 = set -x; $(SPHINX_BUILD)
+sphinx_build = $(sphinx_build_$(V))
+
+define sphinx.build
+$(call sphinx_build,$1) -b $1 -d $(SPHINX_DOCTREES) $(if $(SPHINX_CONFDIR),-c $(SPHINX_CONFDIR)) $(SPHINX_OPTS) $(sphinx_$1_opts) -- $(SPHINX_SOURCE) $(call sphinx.output,$1)
+
+endef
+
+define sphinx.output
+$(if $(sphinx_$1_output),$(sphinx_$1_output),$1)
+endef
+
+# Targets.
+
+ifneq ($(wildcard $(if $(SPHINX_CONFDIR),$(SPHINX_CONFDIR),$(SPHINX_SOURCE))/conf.py),)
+docs:: sphinx
+distclean:: distclean-sphinx
+endif
+
+help::
+ $(verbose) printf "%s\n" "" \
+ "Sphinx targets:" \
+ " sphinx Generate Sphinx documentation." \
+ "" \
+ "ReST sources and 'conf.py' file are expected in directory pointed by" \
+ "SPHINX_SOURCE ('doc' by default). SPHINX_FORMATS lists formats to build (only" \
+ "'html' format is generated by default); target directory can be specified by" \
+ 'setting sphinx_$${format}_output, for example: sphinx_html_output = output/html' \
+ "Additional Sphinx options can be set in SPHINX_OPTS."
+
+# Plugin-specific targets.
+
+sphinx:
+ $(foreach F,$(SPHINX_FORMATS),$(call sphinx.build,$F))
+
+distclean-sphinx:
+ $(gen_verbose) rm -rf $(filter-out $(SPHINX_SOURCE),$(foreach F,$(SPHINX_FORMATS),$(call sphinx.output,$F)))
diff --git a/test/plugin_sphinx.mk b/test/plugin_sphinx.mk
new file mode 100644
index 0000000..a31475a
--- /dev/null
+++ b/test/plugin_sphinx.mk
@@ -0,0 +1,180 @@
+# Sphinx plugin.
+
+SPHINX_CASES = build source-dir formats format-opts
+SPHINX_TARGETS = $(addprefix sphinx-,$(SPHINX_CASES))
+
+.PHONY: sphinx $(SPHINX_TARGETS)
+
+sphinx: $(SPHINX_TARGETS)
+
+sphinx-build: build clean
+
+ $i "Bootstrap a new OTP application named $(APP)"
+ $t mkdir $(APP)/
+ $t cp ../erlang.mk $(APP)/
+ $t $(MAKE) -C $(APP) -f erlang.mk bootstrap $v
+
+ $i "Generate Sphinx config"
+ $(call sphinx-generate-doc-skeleton)
+
+ $i "Run Sphinx"
+ $t $(MAKE) -C $(APP) sphinx $v
+
+ $i "Check that documentation was generated"
+ $t test -f $(APP)/html/index.html
+ $t test -f $(APP)/html/manpage.html
+
+ $i "Distclean the application"
+ $t $(MAKE) -C $(APP) distclean $v
+
+ $i "Check that the generated documentation was removed"
+ $t test ! -e $(APP)/html/index.html
+ $t test ! -e $(APP)/html/manpage.html
+
+ $i "Set 'today' macro with command-line options"
+ $t echo "SPHINX_OPTS = -D 'today=erlang_mk_sphinx_today'" >> $(APP)/Makefile
+
+ $i "Run Sphinx"
+ $t $(MAKE) -C $(APP) sphinx $v
+
+ $i "Check that the 'today' macro was defined"
+ $t grep -q erlang_mk_sphinx_today $(APP)/html/manpage.html
+
+sphinx-source-dir: build clean
+
+ $i "Bootstrap a new OTP application named $(APP)"
+ $t mkdir $(APP)/
+ $t cp ../erlang.mk $(APP)/
+ $t $(MAKE) -C $(APP) -f erlang.mk bootstrap $v
+
+ $i "Change documentation source directory"
+ $t echo "SPHINX_SOURCE = documentation" >> $(APP)/Makefile
+
+ $i "Generate Sphinx config"
+ $(call sphinx-generate-doc-skeleton,documentation)
+
+ $i "Run Sphinx (html)"
+ $t $(MAKE) -C $(APP) sphinx $v
+
+ $i "Check that documentation was generated"
+ $t test -f $(APP)/html/index.html
+ $t test -f $(APP)/html/manpage.html
+
+sphinx-formats: build clean
+
+ $i "Bootstrap a new OTP application named $(APP)"
+ $t mkdir $(APP)/
+ $t cp ../erlang.mk $(APP)/
+ $t $(MAKE) -C $(APP) -f erlang.mk bootstrap $v
+
+ $i "Define formats generated by Sphinx"
+ $t echo "SPHINX_FORMATS = html man" >> $(APP)/Makefile
+
+ $i "Generate Sphinx config"
+ $(call sphinx-generate-doc-skeleton)
+
+ $i "Run Sphinx (html + man)"
+ $t $(MAKE) -C $(APP) sphinx $v
+
+ $i "Check that documentation was generated"
+ $t test -f $(APP)/man/sphinx_$(APP).1
+ $t test -f $(APP)/html/index.html
+ $t test -f $(APP)/html/manpage.html
+
+ $i "Distclean the application"
+ $t $(MAKE) -C $(APP) distclean $v
+
+ $i "Check that the generated documentation was removed"
+ $t test ! -e $(APP)/man/sphinx_$(APP).1
+ $t test ! -e $(APP)/html/index.html
+ $t test ! -e $(APP)/html/manpage.html
+
+ $i "Change documentation output directories"
+ $t echo "sphinx_html_output = sphinx/html_output" >> $(APP)/Makefile
+ $t echo "sphinx_man_output = sphinx/man_output" >> $(APP)/Makefile
+
+ $i "Run Sphinx (html + man)"
+ $t $(MAKE) -C $(APP) sphinx $v
+
+ $i "Check that documentation was generated"
+ $t test -f $(APP)/sphinx/man_output/sphinx_$(APP).1
+ $t test -f $(APP)/sphinx/html_output/index.html
+ $t test -f $(APP)/sphinx/html_output/manpage.html
+
+ $i "Distclean the application"
+ $t $(MAKE) -C $(APP) distclean $v
+
+ $i "Check that the generated documentation was removed"
+ $t test ! -e $(APP)/sphinx/man_output/sphinx_$(APP).1
+ $t test ! -e $(APP)/sphinx/html_output/index.html
+ $t test ! -e $(APP)/sphinx/html_output/manpage.html
+
+sphinx-format-opts: build clean
+
+ $i "Bootstrap a new OTP application named $(APP)"
+ $t mkdir $(APP)/
+ $t cp ../erlang.mk $(APP)/
+ $t $(MAKE) -C $(APP) -f erlang.mk bootstrap $v
+
+ $i "Define formats generated by Sphinx"
+ $t echo "SPHINX_FORMATS = html man" >> $(APP)/Makefile
+
+ $i "Change format-specific options"
+ $t echo "sphinx_html_opts = -D 'today=erlang_mk_sphinx_html_today'" >> $(APP)/Makefile
+ $t echo "sphinx_man_opts = -D 'today=erlang_mk_sphinx_man_today'" >> $(APP)/Makefile
+
+ $i "Generate Sphinx config"
+ $(call sphinx-generate-doc-skeleton)
+
+ $i "Run Sphinx (html + man)"
+ $t $(MAKE) -C $(APP) sphinx $v
+
+ $i "Check that the 'today' macro was defined correctly"
+ $t grep -q erlang_mk_sphinx_html_today $(APP)/html/manpage.html
+ $t grep -q erlang_mk_sphinx_man_today $(APP)/man/sphinx_$(APP).1
+
+
+define sphinx-generate-doc-skeleton
+$t mkdir $(APP)/$(if $1,$1,doc)/
+$t printf "%s\n" \
+ "project = '$(APP)'" \
+ "master_doc = 'index'" \
+ "source_suffix = '.rst'" \
+ "man_pages = [('manpage', 'sphinx_$(APP)', 'Man Page', [], 1)]" \
+ "" > $(APP)/$(if $1,$1,doc)/conf.py
+
+$t printf "%s\n" \
+ "***********" \
+ "Sphinx Docs" \
+ "***********" \
+ "" \
+ "ToC" \
+ "===" \
+ "" \
+ ".. toctree::" \
+ "" \
+ " manpage" \
+ "" \
+ "Indices" \
+ "=======" \
+ "" \
+ '* :ref:`genindex`' \
+ '* :ref:`modindex`' \
+ '* :ref:`search`' \
+ "" > $(APP)/$(if $1,$1,doc)/index.rst
+
+$t printf "%s\n" \
+ "********" \
+ "Man Page" \
+ "********" \
+ "" \
+ "Synopsis" \
+ "========" \
+ "" \
+ ".. code-block:: none" \
+ "" \
+ " erlang-sphinx-mk-man [--help]" \
+ "" \
+ "today = |today|" \
+ "" > $(APP)/$(if $1,$1,doc)/manpage.rst
+endef