mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Merged birkenfeld/sphinx into default
This commit is contained in:
commit
4c782604ed
40
CHANGES
40
CHANGES
@ -1,28 +1,39 @@
|
||||
Release 1.3 (in development)
|
||||
============================
|
||||
|
||||
Change support versions
|
||||
-----------------------
|
||||
|
||||
* Drop Python-2.5, 3.1 (support code was completely removed)
|
||||
|
||||
Incompatible changes
|
||||
--------------------
|
||||
|
||||
* Dropped support for Python 2.5 and 3.1.
|
||||
|
||||
* Removed the ``sphinx.ext.oldcmarkup`` extension.
|
||||
|
||||
* The deprecated config values ``exclude_trees``, ``exclude_dirnames`` and
|
||||
``unused_docs`` have been removed.
|
||||
|
||||
* A new node, ``sphinx.addnodes.literal_strong``, has been added, for text that
|
||||
should appear literally (i.e. no smart quotes) in strong font. Custom writers
|
||||
will have to be adapted to handle this node.
|
||||
|
||||
New features
|
||||
------------
|
||||
|
||||
* PR#202: Allow "." and "~" prefixed references in ``:param:`` doc fields
|
||||
for Python.
|
||||
|
||||
* PR#184: Add :confval:`autodoc_mock_imports`, allowing to mock imports of
|
||||
external modules that need not be present when autodocumenting.
|
||||
|
||||
* #925: Allow list-typed config values to be provided on the command line,
|
||||
like ``-D key=val1,val2``.
|
||||
|
||||
* #668: Allow line numbering of ``code-block`` and ``literalinclude`` directives
|
||||
to start at an arbitrary line number, with a new ``lineno-start`` option.
|
||||
|
||||
* PR#172: The :rst:dir:`code-block` and :rst:dir:`literalinclude` directives now
|
||||
can have a ``filename`` option that shows a filename before the code in the
|
||||
output.
|
||||
|
||||
* Prompt for the document language in sphinx-quickstart.
|
||||
|
||||
Bugs fixed
|
||||
@ -126,6 +137,23 @@ Bugs fixed
|
||||
|
||||
* #1285: Avoid name clashes between C domain objects and section titles.
|
||||
|
||||
* #848: Always take the newest code in incremental rebuilds with the
|
||||
:mod:`sphinx.ext.viewcode` extension.
|
||||
|
||||
* #979, #1266: Fix exclude handling in ``sphinx-apidoc``.
|
||||
|
||||
* #1302: Fix regression in :mod:`sphinx.ext.inheritance_diagram` when
|
||||
documenting classes that can't be pickled.
|
||||
|
||||
* #1316: Remove hard-coded ``font-face`` resources from epub theme.
|
||||
|
||||
* #1329: Fix traceback with empty translation msgstr in .po files.
|
||||
|
||||
* #1300: Fix references not working in translated documents in some instances.
|
||||
|
||||
* #1283: Fix a bug in the detection of changed files that would try to access
|
||||
doctrees of deleted documents.
|
||||
|
||||
Documentation
|
||||
-------------
|
||||
|
||||
@ -377,6 +405,8 @@ Features added
|
||||
reference documentation in doc directory provides a ``sphinx.pot`` file with
|
||||
message strings from ``doc/_templates/*.html`` when using ``make gettext``.
|
||||
|
||||
- PR#61,#703: Add support for non-ASCII filename handling.
|
||||
|
||||
* Other builders:
|
||||
|
||||
- Added the Docutils-native XML and pseudo-XML builders. See
|
||||
|
160
doc/Makefile
160
doc/Makefile
@ -4,157 +4,15 @@
|
||||
# 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
|
||||
SOURCEDIR = .
|
||||
BUILDDIR = _build
|
||||
|
||||
# Has to be explicit, otherwise we don't get "make" without targets right.
|
||||
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"
|
||||
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
|
||||
|
||||
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."
|
||||
|
||||
pseudoxml:
|
||||
$(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) _build/pseudoxml
|
||||
@echo
|
||||
@echo "Build finished. The pseudo-XML files are in _build/pseudoxml."
|
||||
# Catch-all target: route all unknown targets to Sphinx using the new
|
||||
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
|
||||
%:
|
||||
$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
|
||||
|
@ -45,7 +45,8 @@ Important points to note:
|
||||
* There is a special object named ``tags`` available in the config file.
|
||||
It can be used to query and change the tags (see :ref:`tags`). Use
|
||||
``tags.has('tag')`` to query, ``tags.add('tag')`` and ``tags.remove('tag')``
|
||||
to change.
|
||||
to change. Only tags set via the ``-t`` command-line option or via
|
||||
``tags.add('tag')`` can be queried using ``tags.has('tag')``.
|
||||
|
||||
|
||||
General configuration
|
||||
@ -113,38 +114,6 @@ General configuration
|
||||
|
||||
.. versionadded:: 1.0
|
||||
|
||||
.. confval:: unused_docs
|
||||
|
||||
A list of document names that are present, but not currently included in the
|
||||
toctree. Use this setting to suppress the warning that is normally emitted
|
||||
in that case.
|
||||
|
||||
.. deprecated:: 1.0
|
||||
Use :confval:`exclude_patterns` or :ref:`metadata` instead.
|
||||
|
||||
.. confval:: exclude_trees
|
||||
|
||||
A list of directory paths, relative to the source directory, that are to be
|
||||
recursively excluded from the search for source files, that is, their
|
||||
subdirectories won't be searched too. The default is ``[]``.
|
||||
|
||||
.. versionadded:: 0.4
|
||||
|
||||
.. deprecated:: 1.0
|
||||
Use :confval:`exclude_patterns` instead.
|
||||
|
||||
.. confval:: exclude_dirnames
|
||||
|
||||
A list of directory names that are to be excluded from any recursive
|
||||
operation Sphinx performs (e.g. searching for source files or copying static
|
||||
files). This is useful, for example, to exclude version-control-specific
|
||||
directories like ``'CVS'``. The default is ``[]``.
|
||||
|
||||
.. versionadded:: 0.5
|
||||
|
||||
.. deprecated:: 1.0
|
||||
Use :confval:`exclude_patterns` instead.
|
||||
|
||||
.. confval:: templates_path
|
||||
|
||||
A list of paths that contain extra templates (or templates that overwrite
|
||||
|
@ -195,6 +195,12 @@ inserting them into the page source under a suitable :rst:dir:`py:module`,
|
||||
|
||||
.. versionadded:: 1.2
|
||||
|
||||
* Add a list of modules in the :confval:`autodoc_mock_imports` to prevent
|
||||
import errors to halt the building process when some external dependencies
|
||||
are not importable at build time.
|
||||
|
||||
.. versionadded:: 1.3
|
||||
|
||||
|
||||
.. rst:directive:: autofunction
|
||||
autodata
|
||||
@ -335,6 +341,14 @@ There are also new config values that you can set:
|
||||
|
||||
.. versionadded:: 1.1
|
||||
|
||||
.. confval:: autodoc_mock_imports
|
||||
|
||||
This value contains a list of modules to be mocked up. This is useful when
|
||||
some external dependencies are not met at build time and break the building
|
||||
process.
|
||||
|
||||
.. versionadded:: 1.3
|
||||
|
||||
|
||||
Docstring preprocessing
|
||||
-----------------------
|
||||
|
@ -188,6 +188,25 @@ Includes
|
||||
The ``prepend`` and ``append`` options, as well as ``tab-width``.
|
||||
|
||||
|
||||
Showing a file name
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. versionadded:: 1.3
|
||||
|
||||
A ``filename`` option can be given to show that name before the code block. For
|
||||
example::
|
||||
|
||||
.. code-block:: python
|
||||
:filename: this.py
|
||||
|
||||
print 'Explicit is better than implicit.'
|
||||
|
||||
|
||||
:rst:dir:`literalinclude` also supports the ``filename`` option, with the
|
||||
additional feature that if you leave the value empty, the shown filename will be
|
||||
exactly the one given as an argument.
|
||||
|
||||
|
||||
.. rubric:: Footnotes
|
||||
|
||||
.. [1] There is a standard ``.. include`` directive, but it raises errors if the
|
||||
|
@ -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))
|
||||
|
@ -81,5 +81,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))
|
||||
|
@ -65,7 +65,7 @@ def write_file(name, text, opts):
|
||||
|
||||
def format_heading(level, text):
|
||||
"""Create a heading of <level> [1, 2 or 3 supported]."""
|
||||
underlining = ['=', '-', '~', ][level-1] * len(text)
|
||||
underlining = ['=', '-', '~', ][level - 1] * len(text)
|
||||
return '%s\n%s\n\n' % (text, underlining)
|
||||
|
||||
|
||||
@ -173,9 +173,6 @@ def recurse_tree(rootpath, excludes, opts):
|
||||
Look for every file in the directory tree and create the corresponding
|
||||
ReST files.
|
||||
"""
|
||||
# use absolute path for root, as relative paths like '../../foo' cause
|
||||
# 'if "/." in root ...' to filter out *all* modules otherwise
|
||||
rootpath = path.normpath(path.abspath(rootpath))
|
||||
# check if the base directory is a package and get its name
|
||||
if INITPY in os.listdir(rootpath):
|
||||
root_package = rootpath.split(path.sep)[-1]
|
||||
@ -185,13 +182,12 @@ def recurse_tree(rootpath, excludes, opts):
|
||||
|
||||
toplevels = []
|
||||
followlinks = getattr(opts, 'followlinks', False)
|
||||
includeprivate = getattr(opts, 'includeprivate', False)
|
||||
for root, subs, files in os.walk(rootpath, followlinks=followlinks):
|
||||
if is_excluded(root, excludes):
|
||||
del subs[:]
|
||||
continue
|
||||
# document only Python module files
|
||||
# document only Python module files (that aren't excluded)
|
||||
py_files = sorted(f for f in files
|
||||
if path.splitext(f)[1] in PY_SUFFIXES)
|
||||
if path.splitext(f)[1] in PY_SUFFIXES and
|
||||
not is_excluded(path.join(root, f), excludes))
|
||||
is_pkg = INITPY in py_files
|
||||
if is_pkg:
|
||||
py_files.remove(INITPY)
|
||||
@ -200,8 +196,14 @@ def recurse_tree(rootpath, excludes, opts):
|
||||
# only accept non-package at toplevel
|
||||
del subs[:]
|
||||
continue
|
||||
# remove hidden ('.') and private ('_') directories
|
||||
subs[:] = sorted(sub for sub in subs if sub[0] not in ['.', '_'])
|
||||
# remove hidden ('.') and private ('_') directories, as well as
|
||||
# excluded dirs
|
||||
if includeprivate:
|
||||
exclude_prefixes = ('.',)
|
||||
else:
|
||||
exclude_prefixes = ('.', '_')
|
||||
subs[:] = sorted(sub for sub in subs if not sub.startswith(exclude_prefixes)
|
||||
and not is_excluded(path.join(root, sub), excludes))
|
||||
|
||||
if is_pkg:
|
||||
# we are in a package with something to document
|
||||
@ -225,47 +227,35 @@ def recurse_tree(rootpath, excludes, opts):
|
||||
|
||||
|
||||
def normalize_excludes(rootpath, excludes):
|
||||
"""
|
||||
Normalize the excluded directory list:
|
||||
* must be either an absolute path or start with rootpath,
|
||||
* otherwise it is joined with rootpath
|
||||
* with trailing slash
|
||||
"""
|
||||
f_excludes = []
|
||||
for exclude in excludes:
|
||||
if not path.isabs(exclude) and not exclude.startswith(rootpath):
|
||||
exclude = path.join(rootpath, exclude)
|
||||
f_excludes.append(path.normpath(exclude) + path.sep)
|
||||
return f_excludes
|
||||
"""Normalize the excluded directory list."""
|
||||
return [path.normpath(path.abspath(exclude)) for exclude in excludes]
|
||||
|
||||
|
||||
def is_excluded(root, excludes):
|
||||
"""
|
||||
Check if the directory is in the exclude list.
|
||||
"""Check if the directory is in the exclude list.
|
||||
|
||||
Note: by having trailing slashes, we avoid common prefix issues, like
|
||||
e.g. an exlude "foo" also accidentally excluding "foobar".
|
||||
"""
|
||||
sep = path.sep
|
||||
if not root.endswith(sep):
|
||||
root += sep
|
||||
root = path.normpath(root)
|
||||
for exclude in excludes:
|
||||
if root.startswith(exclude):
|
||||
if root == exclude:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def main(argv=sys.argv):
|
||||
"""
|
||||
Parse and check the command line arguments.
|
||||
"""
|
||||
"""Parse and check the command line arguments."""
|
||||
parser = optparse.OptionParser(
|
||||
usage="""\
|
||||
usage: %prog [options] -o <output_path> <module_path> [exclude_paths, ...]
|
||||
usage: %prog [options] -o <output_path> <module_path> [exclude_path, ...]
|
||||
|
||||
Look recursively in <module_path> for Python modules and packages and create
|
||||
one reST file with automodule directives per package in the <output_path>.
|
||||
|
||||
The <exclude_path>s can be files and/or directories that will be excluded
|
||||
from generation.
|
||||
|
||||
Note: By default this script will not overwrite already created files.""")
|
||||
|
||||
parser.add_option('-o', '--output-dir', action='store', dest='destdir',
|
||||
@ -327,6 +317,7 @@ Note: By default this script will not overwrite already created files.""")
|
||||
if not path.isdir(opts.destdir):
|
||||
if not opts.dryrun:
|
||||
os.makedirs(opts.destdir)
|
||||
rootpath = path.normpath(path.abspath(rootpath))
|
||||
excludes = normalize_excludes(rootpath, excludes)
|
||||
modules = recurse_tree(rootpath, excludes, opts)
|
||||
if opts.full:
|
||||
|
@ -265,6 +265,12 @@ class Builder(object):
|
||||
self.info(bold('no targets are out of date.'))
|
||||
return
|
||||
|
||||
# filter "docnames" (list of outdated files) by the updated
|
||||
# found_docs of the environment; this will remove docs that
|
||||
# have since been removed
|
||||
if docnames != ['__all__']:
|
||||
docnames = set(docnames) & self.env.found_docs
|
||||
|
||||
# another indirection to support builders that don't build
|
||||
# files individually
|
||||
self.write(docnames, list(updated_docnames), method)
|
||||
@ -289,6 +295,7 @@ class Builder(object):
|
||||
docnames = set(build_docnames) | set(updated_docnames)
|
||||
else:
|
||||
docnames = set(build_docnames)
|
||||
self.app.debug('docnames to write: %s', ', '.join(sorted(docnames)))
|
||||
|
||||
# add all toctree-containing files that may have changed
|
||||
for docname in list(docnames):
|
||||
|
@ -579,10 +579,7 @@ class StandaloneHTMLBuilder(Builder):
|
||||
# then, copy over all user-supplied static files
|
||||
staticentries = [path.join(self.confdir, spath)
|
||||
for spath in self.config.html_static_path]
|
||||
matchers = compile_matchers(
|
||||
self.config.exclude_patterns +
|
||||
['**/' + d for d in self.config.exclude_dirnames]
|
||||
)
|
||||
matchers = compile_matchers(self.config.exclude_patterns)
|
||||
for entry in staticentries:
|
||||
if not path.exists(entry):
|
||||
self.warn('html_static_path entry %r does not exist' % entry)
|
||||
|
@ -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:
|
||||
|
@ -51,10 +51,6 @@ class Config(object):
|
||||
source_suffix = ('.rst', 'env'),
|
||||
source_encoding = ('utf-8-sig', 'env'),
|
||||
exclude_patterns = ([], 'env'),
|
||||
# the next three are all deprecated now
|
||||
unused_docs = ([], 'env'),
|
||||
exclude_trees = ([], 'env'),
|
||||
exclude_dirnames = ([], 'env'),
|
||||
default_role = (None, 'env'),
|
||||
add_function_parentheses = (True, 'env'),
|
||||
add_module_names = (True, 'env'),
|
||||
|
@ -58,6 +58,7 @@ class CodeBlock(Directive):
|
||||
'linenos': directives.flag,
|
||||
'lineno-start': int,
|
||||
'emphasize-lines': directives.unchanged_required,
|
||||
'filename': directives.unchanged_required,
|
||||
}
|
||||
|
||||
def run(self):
|
||||
@ -76,6 +77,9 @@ class CodeBlock(Directive):
|
||||
|
||||
literal = nodes.literal_block(code, code)
|
||||
literal['language'] = self.arguments[0]
|
||||
filename = self.options.get('filename')
|
||||
if filename:
|
||||
literal['filename'] = filename
|
||||
literal['linenos'] = 'linenos' in self.options or \
|
||||
'lineno-start' in self.options
|
||||
extra_args = literal['highlight_args'] = {}
|
||||
@ -111,6 +115,7 @@ class LiteralInclude(Directive):
|
||||
'prepend': directives.unchanged_required,
|
||||
'append': directives.unchanged_required,
|
||||
'emphasize-lines': directives.unchanged_required,
|
||||
'filename': directives.unchanged,
|
||||
}
|
||||
|
||||
def run(self):
|
||||
@ -212,6 +217,11 @@ class LiteralInclude(Directive):
|
||||
retnode['language'] = self.options['language']
|
||||
retnode['linenos'] = 'linenos' in self.options or \
|
||||
'lineno-start' in self.options
|
||||
filename = self.options.get('filename')
|
||||
if filename is not None:
|
||||
if not filename:
|
||||
filename = self.arguments[0]
|
||||
retnode['filename'] = filename
|
||||
extra_args = retnode['highlight_args'] = {}
|
||||
if hl_lines is not None:
|
||||
extra_args['hl_lines'] = hl_lines
|
||||
|
@ -537,6 +537,7 @@ class DefinitionParser(object):
|
||||
'mutable': None,
|
||||
'const': None,
|
||||
'typename': None,
|
||||
'struct': None,
|
||||
'unsigned': set(('char', 'short', 'int', 'long')),
|
||||
'signed': set(('char', 'short', 'int', 'long')),
|
||||
'short': set(('int',)),
|
||||
|
@ -333,9 +333,6 @@ class BuildEnvironment:
|
||||
matchers = compile_matchers(
|
||||
config.exclude_patterns[:] +
|
||||
config.html_extra_path +
|
||||
config.exclude_trees +
|
||||
[d + config.source_suffix for d in config.unused_docs] +
|
||||
['**/' + d for d in config.exclude_dirnames] +
|
||||
['**/_sources', '.#*']
|
||||
)
|
||||
self.found_docs = set(get_matching_docs(
|
||||
|
@ -70,6 +70,35 @@ class Options(dict):
|
||||
return None
|
||||
|
||||
|
||||
class _MockModule(object):
|
||||
"""Used by autodoc_mock_imports."""
|
||||
def __init__(self, *args, **kwargs):
|
||||
pass
|
||||
|
||||
def __call__(self, *args, **kwargs):
|
||||
return _MockModule()
|
||||
|
||||
@classmethod
|
||||
def __getattr__(cls, name):
|
||||
if name in ('__file__', '__path__'):
|
||||
return '/dev/null'
|
||||
elif name[0] == name[0].upper():
|
||||
# Not very good, we assume Uppercase names are classes...
|
||||
mocktype = type(name, (), {})
|
||||
mocktype.__module__ = __name__
|
||||
return mocktype
|
||||
else:
|
||||
return _MockModule()
|
||||
|
||||
def mock_import(modname):
|
||||
if '.' in modname:
|
||||
pkg, _n, mods = modname.rpartition('.')
|
||||
mock_import(pkg)
|
||||
mod = _MockModule()
|
||||
sys.modules[modname] = mod
|
||||
return mod
|
||||
|
||||
|
||||
ALL = object()
|
||||
INSTANCEATTR = object()
|
||||
|
||||
@ -332,6 +361,9 @@ class Documenter(object):
|
||||
self.modname, '.'.join(self.objpath))
|
||||
try:
|
||||
dbg('[autodoc] import %s', self.modname)
|
||||
for modname in self.env.config.autodoc_mock_imports:
|
||||
dbg('[autodoc] adding a mock module %s!', self.modname)
|
||||
mock_import(modname)
|
||||
__import__(self.modname)
|
||||
parent = None
|
||||
obj = self.module = sys.modules[self.modname]
|
||||
@ -1453,6 +1485,7 @@ def setup(app):
|
||||
app.add_config_value('autodoc_member_order', 'alphabetic', True)
|
||||
app.add_config_value('autodoc_default_flags', [], True)
|
||||
app.add_config_value('autodoc_docstring_signature', True, True)
|
||||
app.add_config_value('autodoc_mock_imports', [], True)
|
||||
app.add_event('autodoc-process-docstring')
|
||||
app.add_event('autodoc-process-signature')
|
||||
app.add_event('autodoc-skip-member')
|
||||
|
@ -178,6 +178,9 @@ def render_dot(self, code, options, format, prefix='graphviz'):
|
||||
if p.returncode != 0:
|
||||
raise GraphvizError('dot exited with error:\n[stderr]\n%s\n'
|
||||
'[stdout]\n%s' % (stderr, stdout))
|
||||
if not path.isfile(outfn):
|
||||
raise GraphvizError('dot did not produce an output file:\n[stderr]\n%s\n'
|
||||
'[stdout]\n%s' % (stderr, stdout))
|
||||
return relfn, outfn
|
||||
|
||||
|
||||
|
@ -154,8 +154,18 @@ class InheritanceGraph(object):
|
||||
nodename = self.class_name(cls, parts)
|
||||
fullname = self.class_name(cls, 0)
|
||||
|
||||
# Use first line of docstring as tooltip, if available
|
||||
tooltip = None
|
||||
try:
|
||||
if cls.__doc__:
|
||||
doc = cls.__doc__.strip().split("\n")[0]
|
||||
if doc:
|
||||
tooltip = '"%s"' % doc.replace('"', '\\"')
|
||||
except Exception: # might raise AttributeError for strange classes
|
||||
pass
|
||||
|
||||
baselist = []
|
||||
all_classes[cls] = (nodename, fullname, baselist)
|
||||
all_classes[cls] = (nodename, fullname, baselist, tooltip)
|
||||
for base in cls.__bases__:
|
||||
if not show_builtins and base in builtins:
|
||||
continue
|
||||
@ -168,7 +178,7 @@ class InheritanceGraph(object):
|
||||
for cls in classes:
|
||||
recurse(cls)
|
||||
|
||||
return all_classes
|
||||
return all_classes.values()
|
||||
|
||||
def class_name(self, cls, parts=0):
|
||||
"""Given a class object, return a fully-qualified name.
|
||||
@ -188,7 +198,7 @@ class InheritanceGraph(object):
|
||||
|
||||
def get_all_class_names(self):
|
||||
"""Get all of the class names involved in the graph."""
|
||||
return [fullname for (_, fullname, _) in self.class_info.values()]
|
||||
return [fullname for (_, fullname, _, _) in self.class_info]
|
||||
|
||||
# These are the default attrs for graphviz
|
||||
default_graph_attrs = {
|
||||
@ -241,17 +251,13 @@ class InheritanceGraph(object):
|
||||
res.append('digraph %s {\n' % name)
|
||||
res.append(self._format_graph_attrs(g_attrs))
|
||||
|
||||
for cls, (name, fullname, bases) in sorted(self.class_info.items()):
|
||||
for name, fullname, bases, tooltip in sorted(self.class_info):
|
||||
# Write the node
|
||||
this_node_attrs = n_attrs.copy()
|
||||
if fullname in urls:
|
||||
this_node_attrs['URL'] = '"%s"' % urls[fullname]
|
||||
# Use first line of docstring as tooltip, if available
|
||||
if cls.__doc__:
|
||||
doc = cls.__doc__.strip().split("\n")[0]
|
||||
if doc:
|
||||
doc = doc.replace('"', '\\"')
|
||||
this_node_attrs['tooltip'] = '"%s"' % doc
|
||||
if tooltip:
|
||||
this_node_attrs['tooltip'] = tooltip
|
||||
res.append(' "%s" [%s];\n' %
|
||||
(name, self._format_node_attrs(this_node_attrs)))
|
||||
|
||||
|
@ -24,17 +24,17 @@ def doctree_read(app, doctree):
|
||||
|
||||
def has_tag(modname, fullname, docname):
|
||||
entry = env._viewcode_modules.get(modname, None)
|
||||
if entry is None:
|
||||
try:
|
||||
analyzer = ModuleAnalyzer.for_module(modname)
|
||||
except Exception:
|
||||
env._viewcode_modules[modname] = False
|
||||
return
|
||||
try:
|
||||
analyzer = ModuleAnalyzer.for_module(modname)
|
||||
except Exception:
|
||||
env._viewcode_modules[modname] = False
|
||||
return
|
||||
if not isinstance(analyzer.code, unicode):
|
||||
code = analyzer.code.decode(analyzer.encoding)
|
||||
else:
|
||||
code = analyzer.code
|
||||
if entry is None or entry[0] != code:
|
||||
analyzer.find_tags()
|
||||
if not isinstance(analyzer.code, unicode):
|
||||
code = analyzer.code.decode(analyzer.encoding)
|
||||
else:
|
||||
code = analyzer.code
|
||||
entry = code, analyzer.tags, {}
|
||||
env._viewcode_modules[modname] = entry
|
||||
elif entry is False:
|
||||
@ -142,7 +142,7 @@ def collect_pages(app):
|
||||
if not modnames:
|
||||
return
|
||||
|
||||
app.builder.info(' _modules/index')
|
||||
app.builder.info(' _modules/index', nonl=True)
|
||||
html = ['\n']
|
||||
# the stack logic is needed for using nested lists for submodules
|
||||
stack = ['']
|
||||
|
252
sphinx/make_mode.py
Normal file
252
sphinx/make_mode.py
Normal file
@ -0,0 +1,252 @@
|
||||
# -*- 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>')
|
||||
|
||||
|
||||
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)"),
|
||||
("", "coverage", "to run coverage check of the documentation (if enabled)"),
|
||||
]
|
||||
|
||||
|
||||
class Make(object):
|
||||
|
||||
def __init__(self, srcdir, builddir, opts):
|
||||
self.srcdir = srcdir
|
||||
self.builddir = builddir
|
||||
self.opts = opts
|
||||
|
||||
def builddir_join(self, *comps):
|
||||
return path.join(self.builddir, *comps)
|
||||
|
||||
def build_clean(self):
|
||||
if not path.exists(self.builddir):
|
||||
return
|
||||
elif not path.isdir(self.builddir):
|
||||
print "Error: %r is not a directory!" % self.builddir
|
||||
return 1
|
||||
print "Removing everything under %r..." % self.builddir
|
||||
for item in os.listdir(self.builddir):
|
||||
shutil.rmtree(self.builddir_join(item))
|
||||
|
||||
def build_help(self):
|
||||
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(self):
|
||||
if self.run_generic_build('html') > 0:
|
||||
return 1
|
||||
print
|
||||
print 'Build finished. The HTML pages are in %s.' % self.builddir_join('html')
|
||||
|
||||
def build_dirhtml(self):
|
||||
if self.run_generic_build('dirhtml') > 0:
|
||||
return 1
|
||||
print
|
||||
print 'Build finished. The HTML pages are in %s.' % self.builddir_join('dirhtml')
|
||||
|
||||
def build_singlehtml(self):
|
||||
if self.run_generic_build('singlehtml') > 0:
|
||||
return 1
|
||||
print
|
||||
print 'Build finished. The HTML page is in %s.' % self.builddir_join('singlehtml')
|
||||
|
||||
def build_pickle(self):
|
||||
if self.run_generic_build('pickle') > 0:
|
||||
return 1
|
||||
print
|
||||
print 'Build finished; now you can process the pickle files.'
|
||||
|
||||
def build_json(self):
|
||||
if self.run_generic_build('json') > 0:
|
||||
return 1
|
||||
print
|
||||
print 'Build finished; now you can process the JSON files.'
|
||||
|
||||
def build_htmlhelp(self):
|
||||
if self.run_generic_build('htmlhelp') > 0:
|
||||
return 1
|
||||
print
|
||||
print ('Build finished; now you can run HTML Help Workshop with the '
|
||||
'.hhp project file in %s.') % self.builddir_join('htmlhelp')
|
||||
|
||||
def build_qthelp(self):
|
||||
if self.run_generic_build('qthelp') > 0:
|
||||
return 1
|
||||
print
|
||||
print ('Build finished; now you can run "qcollectiongenerator" with the '
|
||||
'.qhcp project file in %s, like this:') % self.builddir_join('qthelp')
|
||||
print '$ qcollectiongenerator %s.qhcp' % self.builddir_join('qthelp', proj_name)
|
||||
print 'To view the help file:'
|
||||
print '$ assistant -collectionFile %s.qhc' % self.builddir_join('qthelp', proj_name)
|
||||
|
||||
def build_devhelp(self):
|
||||
if self.run_generic_build('devhelp') > 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" % \
|
||||
(self.builddir_join('devhelp'), proj_name)
|
||||
print "$ devhelp"
|
||||
|
||||
def build_epub(self):
|
||||
if self.run_generic_build('epub') > 0:
|
||||
return 1
|
||||
print
|
||||
print 'Build finished. The ePub file is in %s.' % self.builddir_join('epub')
|
||||
|
||||
def build_latex(self):
|
||||
if self.run_generic_build('latex') > 0:
|
||||
return 1
|
||||
print "Build finished; the LaTeX files are in %s." % self.builddir_join('latex')
|
||||
if os.name == 'posix':
|
||||
print "Run `make' in that directory to run these through (pdf)latex"
|
||||
print "(use `make latexpdf' here to do that automatically)."
|
||||
|
||||
def build_latexpdf(self):
|
||||
if self.run_generic_build('latex') > 0:
|
||||
return 1
|
||||
os.system('make -C %s all-pdf' % self.builddir_join('latex'))
|
||||
|
||||
def build_latexpdfja(self):
|
||||
if self.run_generic_build('latex') > 0:
|
||||
return 1
|
||||
os.system('make -C %s all-pdf-ja' % self.builddir_join('latex'))
|
||||
|
||||
def build_text(self):
|
||||
if self.run_generic_build('text') > 0:
|
||||
return 1
|
||||
print
|
||||
print 'Build finished. The text files are in %s.' % self.builddir_join('text')
|
||||
|
||||
def build_texinfo(self):
|
||||
if self.run_generic_build('texinfo') > 0:
|
||||
return 1
|
||||
print "Build finished; the Texinfo files are in %s." % self.builddir_join('texinfo')
|
||||
if os.name == 'posix':
|
||||
print "Run `make' in that directory to run these through makeinfo"
|
||||
print "(use `make info' here to do that automatically)."
|
||||
|
||||
def build_info(self):
|
||||
if self.run_generic_build('texinfo') > 0:
|
||||
return 1
|
||||
os.system('make -C %s info' % self.builddir_join('texinfo'))
|
||||
|
||||
def build_gettext(self):
|
||||
dtdir = self.builddir_join('gettext', '.doctrees')
|
||||
if self.run_generic_build('gettext', doctreedir=dtdir) > 0:
|
||||
return 1
|
||||
print
|
||||
print 'Build finished. The message catalogs are in %s.' % self.builddir_join('gettext')
|
||||
|
||||
def build_changes(self):
|
||||
if self.run_generic_build('changes') > 0:
|
||||
return 1
|
||||
print
|
||||
print 'Build finished. The overview file is in %s.' % self.builddir_join('changes')
|
||||
|
||||
def build_linkcheck(self):
|
||||
res = self.run_generic_build('linkcheck')
|
||||
print
|
||||
print ('Link check complete; look for any errors in the above output '
|
||||
'or in %s.') % self.builddir_join('linkcheck', 'output.txt')
|
||||
return res
|
||||
|
||||
def build_doctest(self):
|
||||
res = self.run_generic_build('doctest')
|
||||
print ("Testing of doctests in the sources finished, look at the "
|
||||
"results in %s." % self.builddir_join('doctest', 'output.txt'))
|
||||
return res
|
||||
|
||||
def build_coverage(self):
|
||||
if self.run_generic_build('coverage') > 0:
|
||||
print "Has the coverage extension been enabled?"
|
||||
return 1
|
||||
print
|
||||
print ("Testing of coverage in the sources finished, look at the "
|
||||
"results in %s." % self.builddir_join('coverage'))
|
||||
|
||||
def build_xml(self):
|
||||
if self.run_generic_build('xml') > 0:
|
||||
return 1
|
||||
print
|
||||
print 'Build finished. The XML files are in %s.' % self.builddir_join('xml')
|
||||
|
||||
def build_pseudoxml(self):
|
||||
if self.run_generic_build('pseudoxml') > 0:
|
||||
return 1
|
||||
print
|
||||
print 'Build finished. The pseudo-XML files are in %s.' % self.builddir_join('pseudoxml')
|
||||
|
||||
def run_generic_build(self, builder, doctreedir=None):
|
||||
# compatibility with old Makefile
|
||||
papersize = os.getenv('PAPER', '')
|
||||
opts = self.opts
|
||||
if papersize in ('a4', 'letter'):
|
||||
opts.extend(['-D', 'latex_paper_size=' + papersize])
|
||||
if doctreedir is None:
|
||||
doctreedir = self.builddir_join('doctrees')
|
||||
return call([sys.executable, sys.argv[0], '-b', builder,
|
||||
'-d', doctreedir, self.srcdir, self.builddir_join(builder)] + opts)
|
||||
|
||||
|
||||
def run_make_mode(args):
|
||||
if len(args) < 3:
|
||||
print >>sys.stderr, ('Error: at least 3 arguments (builder, source '
|
||||
'dir, build dir) are required.')
|
||||
return 1
|
||||
make = Make(args[1], args[2], args[3:])
|
||||
run_method = 'build_' + args[0]
|
||||
if hasattr(make, run_method):
|
||||
return getattr(make, run_method)()
|
||||
return make.run_generic_build(args[0])
|
@ -840,6 +840,76 @@ if "%%1" == "pseudoxml" (
|
||||
:end
|
||||
'''
|
||||
|
||||
# This will become the Makefile template for Sphinx 1.5.
|
||||
MAKEFILE_NEW = u'''\
|
||||
# Minimal makefile for Sphinx documentation
|
||||
#
|
||||
|
||||
# You can set these variables from the command line.
|
||||
SPHINXOPTS =
|
||||
SPHINXBUILD = sphinx-build
|
||||
SPHINXPROJ = %(project_fn)s
|
||||
SOURCEDIR = %(rsrcdir)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 "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
|
||||
|
||||
# You can add custom targets here.
|
||||
|
||||
# Catch-all target: route all unknown targets to Sphinx using the new
|
||||
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
|
||||
%:
|
||||
\t@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(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):
|
||||
|
@ -14,6 +14,7 @@
|
||||
|
||||
import sys
|
||||
import os
|
||||
import types
|
||||
from StringIO import StringIO
|
||||
from distutils.cmd import Command
|
||||
|
||||
@ -98,6 +99,19 @@ class BuildDoc(Command):
|
||||
return root
|
||||
return None
|
||||
|
||||
# Overriding distutils' Command._ensure_stringlike which doesn't support
|
||||
# unicode, causing finalize_options to fail if invoked again. Workaround
|
||||
# for http://bugs.python.org/issue19570
|
||||
def _ensure_stringlike(self, option, what, default=None):
|
||||
val = getattr(self, option)
|
||||
if val is None:
|
||||
setattr(self, option, default)
|
||||
return default
|
||||
elif not isinstance(val, types.StringTypes):
|
||||
raise DistutilsOptionError("'%s' must be a %s (got `%s`)"
|
||||
% (option, what, val))
|
||||
return val
|
||||
|
||||
def finalize_options(self):
|
||||
if self.source_dir is None:
|
||||
self.source_dir = self._guess_source_dir()
|
||||
|
@ -9,6 +9,10 @@ ARCHIVEPRREFIX =
|
||||
# Additional LaTeX options
|
||||
LATEXOPTS =
|
||||
|
||||
LATEX = latex
|
||||
PDFLATEX = pdflatex
|
||||
MAKEINDEX = makeindex
|
||||
|
||||
all: $(ALLPDF)
|
||||
all-pdf: $(ALLPDF)
|
||||
all-dvi: $(ALLDVI)
|
||||
@ -43,20 +47,20 @@ bz2: tar
|
||||
# The number of LaTeX runs is quite conservative, but I don't expect it
|
||||
# to get run often, so the little extra time won't hurt.
|
||||
%.dvi: %.tex
|
||||
latex $(LATEXOPTS) '$<'
|
||||
latex $(LATEXOPTS) '$<'
|
||||
latex $(LATEXOPTS) '$<'
|
||||
-makeindex -s python.ist '$(basename $<).idx'
|
||||
latex $(LATEXOPTS) '$<'
|
||||
latex $(LATEXOPTS) '$<'
|
||||
$(LATEX) $(LATEXOPTS) '$<'
|
||||
$(LATEX) $(LATEXOPTS) '$<'
|
||||
$(LATEX) $(LATEXOPTS) '$<'
|
||||
-$(MAKEINDEX) -s python.ist '$(basename $<).idx'
|
||||
$(LATEX) $(LATEXOPTS) '$<'
|
||||
$(LATEX) $(LATEXOPTS) '$<'
|
||||
|
||||
%.pdf: %.tex
|
||||
pdflatex $(LATEXOPTS) '$<'
|
||||
pdflatex $(LATEXOPTS) '$<'
|
||||
pdflatex $(LATEXOPTS) '$<'
|
||||
-makeindex -s python.ist '$(basename $<).idx'
|
||||
pdflatex $(LATEXOPTS) '$<'
|
||||
pdflatex $(LATEXOPTS) '$<'
|
||||
$(PDFLATEX) $(LATEXOPTS) '$<'
|
||||
$(PDFLATEX) $(LATEXOPTS) '$<'
|
||||
$(PDFLATEX) $(LATEXOPTS) '$<'
|
||||
-$(MAKEINDEX) -s python.ist '$(basename $<).idx'
|
||||
$(PDFLATEX) $(LATEXOPTS) '$<'
|
||||
$(PDFLATEX) $(LATEXOPTS) '$<'
|
||||
|
||||
clean:
|
||||
rm -f *.dvi *.log *.ind *.aux *.toc *.syn *.idx *.out *.ilg *.pla
|
||||
|
@ -462,3 +462,10 @@ div.viewcode-block:target {
|
||||
border-top: 1px solid #ac9;
|
||||
border-bottom: 1px solid #ac9;
|
||||
}
|
||||
|
||||
div.code-block-filename {
|
||||
background-color: #ddd;
|
||||
color: #333;
|
||||
padding: 2px 5px;
|
||||
font-size: small;
|
||||
}
|
||||
|
@ -471,6 +471,20 @@ table.highlighttable td {
|
||||
padding: 0 0.5em 0 0.5em;
|
||||
}
|
||||
|
||||
div.code-block-filename {
|
||||
padding: 2px 5px;
|
||||
font-size: small;
|
||||
}
|
||||
|
||||
div.code-block-filename tt {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
div.code-block-filename + pre,
|
||||
div.code-block-filename + div.highlight > pre {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
tt.descname {
|
||||
background-color: transparent;
|
||||
font-weight: bold;
|
||||
|
@ -168,6 +168,9 @@ var Documentation = {
|
||||
var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : [];
|
||||
if (terms.length) {
|
||||
var body = $('div.body');
|
||||
if (!body.length) {
|
||||
body = $('body');
|
||||
}
|
||||
window.setTimeout(function() {
|
||||
$.each(terms, function() {
|
||||
body.highlightText(this.toLowerCase(), 'highlighted');
|
||||
|
@ -308,3 +308,8 @@ div.viewcode-block:target {
|
||||
border-top: 1px solid #ac9;
|
||||
border-bottom: 1px solid #ac9;
|
||||
}
|
||||
|
||||
div.code-block-filename {
|
||||
color: #efefef;
|
||||
background-color: #1c4e63;
|
||||
}
|
||||
|
@ -339,7 +339,7 @@ dl.glossary dt {
|
||||
/* -- code displays --------------------------------------------------------- */
|
||||
|
||||
pre {
|
||||
font-family: "LiberationNarrow", monospace;
|
||||
font-family: monospace;
|
||||
overflow: auto;
|
||||
overflow-y: hidden;
|
||||
}
|
||||
@ -360,7 +360,7 @@ table.highlighttable td {
|
||||
}
|
||||
|
||||
tt {
|
||||
font-family: "LiberationNarrow", monospace;
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
tt.descname {
|
||||
@ -432,6 +432,7 @@ table .link-target {
|
||||
|
||||
/* -- font-face ------------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
@font-face {
|
||||
font-family: "LiberationNarrow";
|
||||
font-style: normal;
|
||||
@ -460,4 +461,4 @@ table .link-target {
|
||||
src: url("res:///Data/fonts/LiberationNarrow-BoldItalic.otf")
|
||||
format("opentype");
|
||||
}
|
||||
|
||||
*/
|
@ -243,3 +243,9 @@ div.viewcode-block:target {
|
||||
border-top: 1px solid #ac9;
|
||||
border-bottom: 1px solid #ac9;
|
||||
}
|
||||
|
||||
div.code-block-filename {
|
||||
background-color: #ddd;
|
||||
color: #222;
|
||||
border: 1px solid #C6C9CB;
|
||||
}
|
||||
|
@ -340,3 +340,8 @@ tt.xref {
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
div.code-block-filename {
|
||||
background-color: #ddd;
|
||||
color: #222;
|
||||
}
|
||||
|
@ -337,3 +337,9 @@ div.viewcode-block:target {
|
||||
border-top: 1px solid #ac9;
|
||||
border-bottom: 1px solid #ac9;
|
||||
}
|
||||
|
||||
div.code-block-filename {
|
||||
background-color: #ddd;
|
||||
color: #222;
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
|
@ -698,3 +698,7 @@ div.viewcode-block:target {
|
||||
margin: -1px -10px;
|
||||
padding: 0 10px;
|
||||
}
|
||||
|
||||
div.code-block-filename {
|
||||
background-color: #cceeff;
|
||||
}
|
||||
|
@ -195,7 +195,10 @@ class Locale(Transform):
|
||||
patch = new_document(source, settings)
|
||||
CustomLocaleReporter(node.source, node.line).set_reporter(patch)
|
||||
parser.parse(msgstr, patch)
|
||||
patch = patch[0]
|
||||
try:
|
||||
patch = patch[0]
|
||||
except IndexError: # empty node
|
||||
pass
|
||||
# XXX doctest and other block markup
|
||||
if not isinstance(patch, nodes.paragraph):
|
||||
continue # skip for now
|
||||
@ -238,8 +241,7 @@ class Locale(Transform):
|
||||
self.document.ids.pop(_id, None)
|
||||
|
||||
# re-entry with new named section node.
|
||||
self.document.note_implicit_target(
|
||||
section_node, section_node)
|
||||
self.document.note_implicit_target(section_node)
|
||||
|
||||
# replace target's refname to new target name
|
||||
def is_named_target(node):
|
||||
@ -298,7 +300,10 @@ class Locale(Transform):
|
||||
patch = new_document(source, settings)
|
||||
CustomLocaleReporter(node.source, node.line).set_reporter(patch)
|
||||
parser.parse(msgstr, patch)
|
||||
patch = patch[0]
|
||||
try:
|
||||
patch = patch[0]
|
||||
except IndexError: # empty node
|
||||
pass
|
||||
# XXX doctest and other block markup
|
||||
if not isinstance(patch, nodes.paragraph):
|
||||
continue # skip for now
|
||||
|
@ -267,6 +267,9 @@ class HTMLTranslator(BaseTranslator):
|
||||
**highlight_args)
|
||||
starttag = self.starttag(node, 'div', suffix='',
|
||||
CLASS='highlight-%s' % lang)
|
||||
if node.has_key('filename'):
|
||||
starttag += '<div class="code-block-filename"><tt>%s</tt></div>' % (
|
||||
node['filename'],)
|
||||
self.body.append(starttag + highlighted + '</div>\n')
|
||||
raise nodes.SkipNode
|
||||
|
||||
|
@ -1337,6 +1337,11 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
||||
highlight_args['force'] = True
|
||||
if 'linenos' in node:
|
||||
linenos = node['linenos']
|
||||
filename = node.get('filename')
|
||||
if filename:
|
||||
self.body.append('\n{\\colorbox[rgb]{0.9,0.9,0.9}'
|
||||
'{\\makebox[\\textwidth][l]'
|
||||
'{\\small\\texttt{%s}}}}\n' % (filename,))
|
||||
def warner(msg):
|
||||
self.builder.warn(msg, (self.curfilestack[-1], node.line))
|
||||
hlcode = self.highlighter.highlight_block(code, lang, warn=warner,
|
||||
|
@ -45,3 +45,5 @@ Just testing a few autodoc possibilities...
|
||||
:members: ca1, ia1
|
||||
|
||||
Specific members (2 total)
|
||||
|
||||
.. automodule:: autodoc_missing_imports
|
||||
|
9
tests/root/autodoc_missing_imports.py
Normal file
9
tests/root/autodoc_missing_imports.py
Normal file
@ -0,0 +1,9 @@
|
||||
|
||||
import missing_module
|
||||
from missing_module import missing_name
|
||||
import missing_package1.missing_module1
|
||||
from missing_package2 import missing_module2
|
||||
from missing_package3.missing_module3 import missing_name
|
||||
|
||||
class TestAutodoc(object):
|
||||
"""TestAutodoc docstring."""
|
@ -23,7 +23,6 @@ copyright = '2010, Georg Brandl & Team'
|
||||
version = '0.6'
|
||||
release = '0.6alpha1'
|
||||
today_fmt = '%B %d, %Y'
|
||||
# unused_docs = []
|
||||
exclude_patterns = ['_build', '**/excluded.*']
|
||||
keep_warnings = True
|
||||
pygments_style = 'sphinx'
|
||||
@ -71,6 +70,13 @@ autosummary_generate = ['autosummary']
|
||||
extlinks = {'issue': ('http://bugs.python.org/issue%s', 'issue '),
|
||||
'pyurl': ('http://python.org/%s', None)}
|
||||
|
||||
autodoc_mock_imports = [
|
||||
'missing_module',
|
||||
'missing_package1.missing_module1',
|
||||
'missing_package2.missing_module2',
|
||||
'missing_package3.missing_module3',
|
||||
]
|
||||
|
||||
# modify tags from conf.py
|
||||
tags.add('confpytag')
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user