summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorg Brandl <georg@python.org>2014-01-11 19:36:05 +0100
committerGeorg Brandl <georg@python.org>2014-01-11 19:36:05 +0100
commit91d92be8adae2e44e1e23e1c07b7088c35261abf (patch)
tree80127b8a18ea75e91efaeb5b547e6cd60aa5bb7e
parent1f83f01adfd3709dbce0059469b01d5078715a31 (diff)
downloadsphinx-git-91d92be8adae2e44e1e23e1c07b7088c35261abf.tar.gz
Add "make mode" to sphinx-build, invoked by the -M flag.
This is intended to do almost all of what the quickstart-generated Makefile and make.bat did, but within Sphinx. The advantages are: * no duplication between Unix and Windows files * updates and fixes are propagated (the generated makefiles never update) * more Python code, less shell code!
-rw-r--r--doc/Makefile166
-rwxr-xr-xsphinx-build.py7
-rw-r--r--sphinx/__init__.py6
-rw-r--r--sphinx/cmdline.py36
-rw-r--r--sphinx/make_mode.py202
-rw-r--r--sphinx/quickstart.py66
6 files changed, 316 insertions, 167 deletions
diff --git a/doc/Makefile b/doc/Makefile
index 831c12c52..d799c3658 100644
--- a/doc/Makefile
+++ b/doc/Makefile
@@ -4,157 +4,21 @@
# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = python ../sphinx-build.py
-PAPER =
-
-PAPEROPT_a4 = -D latex_paper_size=a4
-PAPEROPT_letter = -D latex_paper_size=letter
-ALLSPHINXOPTS = -d _build/doctrees $(PAPEROPT_$(PAPER)) \
- $(SPHINXOPTS) $(O) .
-I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) $(O) .
-
-.PHONY: help clean html dirhtml singlehtml text man pickle json htmlhelp \
- qthelp devhelp epub latex latexpdf changes linkcheck doctest xml \
- pseudoxml
+SPHINXPROJ = sphinx
+BUILDDIR = _build
+
+# User-friendly check for sphinx-build
+ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1)
+$(error \
+The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx \
+installed, then set the SPHINXBUILD environment variable to point \
+to the full path of the '$(SPHINXBUILD)' executable. Alternatively you \
+can add the directory with the executable to your PATH. \
+If you don't have Sphinx installed, grab it from http://sphinx-doc.org/)
+endif
help:
- @echo "Please use \`make <target>' where <target> is one of"
- @echo " html to make standalone HTML files"
- @echo " dirhtml to make HTML files called index.html in directories"
- @echo " singlehtml to make one big HTML file"
- @echo " text to make text files"
- @echo " man to make manual pages"
- @echo " pickle to make pickle files"
- @echo " json to make json files"
- @echo " htmlhelp to make HTML files and a HTML help project"
- @echo " qthelp to make Qt help files and project"
- @echo " devhelp to make Devhelp files and project"
- @echo " epub to make an epub file"
- @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
- @echo " latexpdf to make LaTeX files and run pdflatex"
- @echo " texinfo to make Texinfo files"
- @echo " info to make Texinfo files and run them through makeinfo"
- @echo " gettext to make PO message catalogs"
- @echo " changes to make an overview over all changed/added/deprecated items"
- @echo " linkcheck to check all external links for integrity"
-
-clean:
- rm -rf _build/*
-
-html:
- $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) _build/html
- @echo
- @echo "Build finished. The HTML pages are in _build/html."
-
-dirhtml:
- $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) _build/dirhtml
- @echo
- @echo "Build finished. The HTML pages are in _build/dirhtml."
-
-singlehtml:
- $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) _build/singlehtml
- @echo
- @echo "Build finished. The HTML page is in _build/singlehtml."
-
-text:
- $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) _build/text
- @echo
- @echo "Build finished."
-
-man:
- $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) _build/man
- @echo
- @echo "Build finished."
-
-pickle:
- $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) _build/pickle
- @echo
- @echo "Build finished."
-
-json:
- $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) _build/json
- @echo
- @echo "Build finished."
-
-htmlhelp:
- $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) _build/htmlhelp
- @echo
- @echo "Build finished; now you can run HTML Help Workshop with the" \
- ".hhp project file in _build/htmlhelp."
-
-qthelp:
- $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) _build/qthelp
- @echo
- @echo "Build finished; now you can run qcollectiongenerator with the" \
- ".qhcp project file in build/qthelp."
- @echo "# qcollectiongenerator _build/qthelp/Sphinx.qhcp"
- @echo "To view the help collection:"
- @echo "# assistant -collectionFile _build/qthelp/Sphinx.qhc"
-
-devhelp:
- $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) _build/devhelp
- @echo
- @echo "Build finished."
- @echo "To view the help file:"
- @echo "# mkdir -p $$HOME/.local/share/devhelp/sphinx"
- @echo "# ln -s _build/devhelp $$HOME/.local/share/devhelp/sphinx"
- @echo "# devhelp"
-
-epub:
- $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) _build/epub
- @echo
- @echo "Build finished. The epub file is in _build/epub."
-
-latex:
- $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) _build/latex
- @echo
- @echo "Build finished; the LaTeX files are in _build/latex."
- @echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \
- "run these through (pdf)latex."
-
-latexpdf:
- $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) _build/latex
- @echo "Running LaTeX files through pdflatex..."
- make -C _build/latex all-pdf
- @echo "pdflatex finished; the PDF files are in _build/latex."
-
-gettext:
- $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) _build/locale
- @echo
- @echo "Build finished. The message catalogs are in _build/locale."
-
-changes:
- $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) _build/changes
- @echo
- @echo "The overview file is in _build/changes."
-
-linkcheck:
- $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) _build/linkcheck
- @echo
- @echo "Link check complete; look for any errors in the above output " \
- "or in _build/linkcheck/output.txt."
-
-doctest:
- $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) _build/doctest
-
-texinfo:
- $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) _build/texinfo
- @echo
- @echo "Build finished. The Texinfo files are in _build/texinfo."
- @echo "Run \`make' in that directory to run these through makeinfo" \
- "(use \`make info' here to do that automatically)."
-
-info:
- $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) _build/texinfo
- @echo "Running Texinfo files through makeinfo..."
- make -C _build/texinfo info
- @echo "makeinfo finished; the Info files are in _build/texinfo."
-
-xml:
- $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) _build/xml
- @echo
- @echo "Build finished. The XML files are in _build/XML."
+ @$(SPHINXBUILD) -M help "$(BUILDDIR)" $(SPHINXOPTS) $(O)
-pseudoxml:
- $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) _build/pseudoxml
- @echo
- @echo "Build finished. The pseudo-XML files are in _build/pseudoxml."
+%:
+ @$(SPHINXBUILD) -M $@ "$(BUILDDIR)" $(SPHINXOPTS) $(O)
diff --git a/sphinx-build.py b/sphinx-build.py
index 6737d0729..54bdb5293 100755
--- a/sphinx-build.py
+++ b/sphinx-build.py
@@ -11,5 +11,8 @@
import sys
if __name__ == '__main__':
- from sphinx import main
- sys.exit(main(sys.argv))
+ from sphinx import main, make_main
+ if sys.argv[1:2] == ['-M']:
+ sys.exit(make_main(sys.argv))
+ else:
+ sys.exit(main(sys.argv))
diff --git a/sphinx/__init__.py b/sphinx/__init__.py
index d41d4424a..8a1b97f70 100644
--- a/sphinx/__init__.py
+++ b/sphinx/__init__.py
@@ -80,5 +80,11 @@ def main(argv=sys.argv):
return cmdline.main(argv)
+def make_main(argv=sys.argv):
+ """Sphinx build "make mode" entry."""
+ from sphinx import make_mode
+ return make_mode.run_make_mode(argv[2:])
+
+
if __name__ == '__main__':
sys.exit(main(sys.argv))
diff --git a/sphinx/cmdline.py b/sphinx/cmdline.py
index e5ad3ab5b..f4a09e161 100644
--- a/sphinx/cmdline.py
+++ b/sphinx/cmdline.py
@@ -42,6 +42,7 @@ General options
-d <path> path for the cached environment and doctree files
(default: outdir/.doctrees)
-j <N> build in parallel with N processes where possible
+-M <builder> "make" mode -- used by Makefile, like "sphinx-build -M html"
Build configuration options
^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -82,19 +83,28 @@ def main(argv):
# Windows' poor cmd box doesn't understand ANSI sequences
nocolor()
+ # parse options
try:
opts, args = getopt.getopt(argv[1:], 'ab:t:d:c:CD:A:nNEqQWw:PThvj:',
['help', 'version'])
- allopts = set(opt[0] for opt in opts)
- if '-h' in allopts or '--help' in allopts:
- usage(argv)
- print >>sys.stderr
- print >>sys.stderr, 'For more information, see '\
- '<http://sphinx-doc.org/>.'
- return 0
- if '--version' in allopts:
- print 'Sphinx (sphinx-build) %s' % __version__
- return 0
+ except getopt.error, err:
+ usage(argv, 'Error: %s' % err)
+ return 1
+
+ # handle basic options
+ allopts = set(opt[0] for opt in opts)
+ # help and version options
+ if '-h' in allopts or '--help' in allopts:
+ usage(argv)
+ print >>sys.stderr
+ print >>sys.stderr, 'For more information, see <http://sphinx-doc.org/>.'
+ return 0
+ if '--version' in allopts:
+ print 'Sphinx (sphinx-build) %s' % __version__
+ return 0
+
+ # get paths (first and second positional argument)
+ try:
srcdir = confdir = abspath(args[0])
if not path.isdir(srcdir):
print >>sys.stderr, 'Error: Cannot find source directory `%s\'.' % (
@@ -103,12 +113,9 @@ def main(argv):
if not path.isfile(path.join(srcdir, 'conf.py')) and \
'-c' not in allopts and '-C' not in allopts:
print >>sys.stderr, ('Error: Source directory doesn\'t '
- 'contain conf.py file.')
+ 'contain a conf.py file.')
return 1
outdir = abspath(args[1])
- except getopt.error, err:
- usage(argv, 'Error: %s' % err)
- return 1
except IndexError:
usage(argv, 'Error: Insufficient arguments.')
return 1
@@ -118,6 +125,7 @@ def main(argv):
'encoding (%r).' % fs_encoding)
return 1
+ # handle remaining filename arguments
filenames = args[2:]
err = 0
for filename in filenames:
diff --git a/sphinx/make_mode.py b/sphinx/make_mode.py
new file mode 100644
index 000000000..5ef065a5d
--- /dev/null
+++ b/sphinx/make_mode.py
@@ -0,0 +1,202 @@
+# -*- coding: utf-8 -*-
+"""
+ sphinx.make_mode
+ ~~~~~~~~~~~~~~~~
+
+ sphinx-build -M command-line handling.
+
+ This replaces the old, platform-dependent and once-generated content
+ of Makefile / make.bat.
+
+ This is in its own module so that importing it is fast. It should not
+ import the main Sphinx modules (like sphinx.applications, sphinx.builders).
+
+ :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS.
+ :license: BSD, see LICENSE for details.
+"""
+
+import os
+import sys
+import shutil
+from os import path
+from subprocess import call
+
+import sphinx
+from sphinx.util.console import bold, blue
+
+proj_name = os.getenv('SPHINXPROJ', '<project>')
+
+def build_clean(builddir, opts):
+ if not path.exists(builddir):
+ return
+ elif not path.isdir(builddir):
+ print "Error: %r is not a directory!" % builddir
+ return 1
+ print "removing everything under %r..." % builddir
+ for item in os.listdir(builddir):
+ shutil.rmtree(path.join(builddir, item))
+
+BUILDERS = [
+ ("", "html", "to make standalone HTML files"),
+ ("", "dirhtml", "to make HTML files named index.html in directories"),
+ ("", "singlehtml","to make a single large HTML file"),
+ ("", "pickle", "to make pickle files"),
+ ("", "json", "to make JSON files"),
+ ("", "htmlhelp", "to make HTML files and a HTML help project"),
+ ("", "qthelp", "to make HTML files and a qthelp project"),
+ ("", "devhelp", "to make HTML files and a Devhelp project"),
+ ("", "epub", "to make an epub"),
+ ("", "latex", "to make LaTeX files, you can set PAPER=a4 or PAPER=letter"),
+ ("posix", "latexpdf", "to make LaTeX files and run them through pdflatex"),
+ ("posix", "latexpdfja","to make LaTeX files and run them through platex/dvipdfmx"),
+ ("", "text", "to make text files"),
+ ("", "man", "to make manual pages"),
+ ("", "texinfo", "to make Texinfo files"),
+ ("posix", "info", "to make Texinfo files and run them through makeinfo"),
+ ("", "gettext", "to make PO message catalogs"),
+ ("", "changes", "to make an overview of all changed/added/deprecated items"),
+ ("", "xml", "to make Docutils-native XML files"),
+ ("", "pseudoxml", "to make pseudoxml-XML files for display purposes"),
+ ("", "linkcheck", "to check all external links for integrity"),
+ ("", "doctest", "to run all doctests embedded in the documentation (if enabled)"),
+]
+
+def build_help(builddir, opts):
+ print bold("Sphinx v%s" % sphinx.__version__)
+ print "Please use `make %s' where %s is one of" % ((blue('target'),)*2)
+ for osname, bname, description in BUILDERS:
+ if not osname or os.name == osname:
+ print ' %s %s' % (blue(bname.ljust(10)), description)
+
+
+def build_html(builddir, opts):
+ if run_generic_build('html', builddir, opts) > 0:
+ return 1
+ print
+ print 'Build finished. The HTML pages are in %s.' % path.join(builddir, 'html')
+
+def build_dirhtml(builddir, opts):
+ if run_generic_build('dirhtml', builddir, opts) > 0:
+ return 1
+ print
+ print 'Build finished. The HTML pages are in %s.' % path.join(builddir, 'dirhtml')
+
+def build_singlehtml(builddir, opts):
+ if run_generic_build('singlehtml', builddir, opts) > 0:
+ return 1
+ print
+ print 'Build finished. The HTML page is in %s.' % path.join(builddir, 'singlehtml')
+
+def build_pickle(builddir, opts):
+ if run_generic_build('pickle', builddir, opts) > 0:
+ return 1
+ print
+ print 'Build finished; now you can process the pickle files.'
+
+def build_json(builddir, opts):
+ if run_generic_build('json', builddir, opts) > 0:
+ return 1
+ print
+ print 'Build finished; now you can process the JSON files.'
+
+def build_htmlhelp(builddir, opts):
+ if run_generic_build('htmlhelp', builddir, opts) > 0:
+ return 1
+ print
+ print ('Build finished; now you can run HTML Help Workshop with the '
+ '.hhp project file in %s.') % path.join(builddir, 'htmlhelp')
+
+def build_qthelp(builddir, opts):
+ if run_generic_build('qthelp', builddir, opts) > 0:
+ return 1
+ print
+ print ('Build finished; now you can run "qcollectiongenerator" with the '
+ '.qhcp project file in %s, like this:') % path.join(builddir, 'qthelp')
+ print '$ qcollectiongenerator %s.qhcp' % path.join(builddir, 'qthelp', proj_name)
+ print 'To view the help file:'
+ print '$ assistant -collectionFile %s.qhc' % path.join(builddir, 'qthelp', proj_name)
+
+def build_devhelp(builddir, opts):
+ if run_generic_build('devhelp', builddir, opts) > 0:
+ return 1
+ print
+ print "Build finished."
+ print "To view the help file:"
+ print "$ mkdir -p $HOME/.local/share/devhelp/" + proj_name
+ print "$ ln -s %s $HOME/.local/share/devhelp/%s" % \
+ (path.join(builddir, 'devhelp'), proj_name)
+ print "$ devhelp"
+
+def build_epub(builddir, opts):
+ if run_generic_build('epub', builddir, opts) > 0:
+ return 1
+ print
+ print 'Build finished. The ePub file is in %s.' % path.join(builddir, 'epub')
+
+
+# latex
+# latexpdf
+# latexpdfja
+
+def build_text(builddir, opts):
+ if run_generic_build('text', builddir, opts) > 0:
+ return 1
+ print
+ print 'Build finished. The text files are in %s.' % path.join(builddir, 'text')
+
+# texinfo
+# info
+
+def build_gettext(builddir, opts):
+ dtdir = path.join(builddir, 'gettext', '.doctrees')
+ if run_generic_build('gettext', builddir, opts, doctreedir=dtdir) > 0:
+ return 1
+ print
+ print 'Build finished. The message catalogs are in %s.' % path.join(builddir, 'gettext')
+
+def build_changes(builddir, opts):
+ if run_generic_build('changes', builddir, opts) > 0:
+ return 1
+ print
+ print 'Build finished. The overview file is in %s.' % path.join(builddir, 'changes')
+
+def build_linkcheck(builddir, opts):
+ res = run_generic_build('linkcheck', builddir, opts)
+ print
+ print ('Link check complete; look for any errors in the above output '
+ 'or in %s.') % path.join(builddir, 'linkcheck', 'output.txt')
+ return res
+
+def build_xml(builddir, opts):
+ if run_generic_build('xml', builddir, opts) > 0:
+ return 1
+ print
+ print 'Build finished. The XML files are in %s.' % path.join(builddir, 'xml')
+
+def build_pseudoxml(builddir, opts):
+ if run_generic_build('pseudoxml', builddir, opts) > 0:
+ return 1
+ print
+ print 'Build finished. The pseudo-XML files are in %s.' % path.join(builddir, 'pseudoxml')
+
+
+def run_generic_build(builder, builddir, opts, doctreedir=None):
+ # compatibility with old Makefile
+ papersize = os.getenv('PAPER', '')
+ if papersize in ('a4', 'letter'):
+ opts.extend(['-D', 'latex_paper_size=' + papersize])
+ if doctreedir is None:
+ doctreedir = path.join(builddir, 'doctrees')
+ return call([sys.executable, sys.argv[0], '-b', builder,
+ '-d', doctreedir, '.', path.join(builddir, builder)] + opts)
+
+
+def run_make_mode(args):
+ if len(args) < 2:
+ print >>sys.stderr, ('Error: at least two arguments (builder, build '
+ 'dir) are required.')
+ return 1
+ run_method = 'build_' + args[0]
+ if run_method in globals():
+ return globals()[run_method](args[1], args[2:])
+ return run_generic_build(args[0], args[1], args[2:])
diff --git a/sphinx/quickstart.py b/sphinx/quickstart.py
index f77e2f22b..7ce3ad848 100644
--- a/sphinx/quickstart.py
+++ b/sphinx/quickstart.py
@@ -837,6 +837,72 @@ if "%%1" == "pseudoxml" (
:end
'''
+# This will become the Makefile template for Sphinx 1.5.
+MAKEFILE_NEW = u'''\
+# Makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line.
+SPHINXOPTS =
+SPHINXBUILD = sphinx-build
+SPHINXPROJ = %(project_fn)s
+BUILDDIR = %(rbuilddir)s
+
+# User-friendly check for sphinx-build
+ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1)
+$(error \
+The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx \
+installed, then set the SPHINXBUILD environment variable to point \
+to the full path of the '$(SPHINXBUILD)' executable. Alternatively you \
+can add the directory with the executable to your PATH. \
+If you don't have Sphinx installed, grab it from http://sphinx-doc.org/)
+endif
+
+# Has to be explicit, otherwise we don't get "make" without targets right.
+help:
+\t@$(SPHINXBUILD) -M help "$(BUILDDIR)" $(SPHINXOPTS) $(O)
+
+# Catch-all target using the new "make mode" option.
+%:
+\t@$(SPHINXBUILD) -M $@ "$(BUILDDIR)" $(SPHINXOPTS) $(O)
+'''
+
+# This will become the make.bat template for Sphinx 1.5.
+BATCHFILE_NEW = u'''\
+@ECHO OFF
+
+REM Command file for Sphinx documentation
+
+if "%%SPHINXBUILD%%" == "" (
+\tset SPHINXBUILD=sphinx-build
+)
+set BUILDDIR=%(rbuilddir)s
+set SPHINXPROJ=%(project_fn)s
+
+if "%%1" == "" goto help
+
+%%SPHINXBUILD%% 2> nul
+if errorlevel 9009 (
+\techo.
+\techo.The 'sphinx-build' command was not found. Make sure you have Sphinx
+\techo.installed, then set the SPHINXBUILD environment variable to point
+\techo.to the full path of the 'sphinx-build' executable. Alternatively you
+\techo.may add the Sphinx directory to PATH.
+\techo.
+\techo.If you don't have Sphinx installed, grab it from
+\techo.http://sphinx-doc.org/
+\texit /b 1
+)
+
+%%SPHINXBUILD%% -M %%1 %%BUILDDIR%% %%SPHINXOPTS%%
+goto end
+
+:help
+%%SPHINXBUILD%% -M help %%BUILDDIR%% %%SPHINXOPTS%%
+
+:end
+'''
+
def mkdir_p(dir):
if path.isdir(dir):