From e05e29f726be51e77f54a06b03faca6c814beff6 Mon Sep 17 00:00:00 2001 From: Markus Zapke-Gr?ndemann Date: Thu, 19 Sep 2013 21:48:54 +0200 Subject: Explain that only tags set via command-line or tags.add() are available --- doc/config.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/config.rst b/doc/config.rst index 70ebacb4..ae41594e 100644 --- a/doc/config.rst +++ b/doc/config.rst @@ -43,7 +43,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 -- cgit v1.2.1 From dccd43b51001bf227a656411837c4c58895c4346 Mon Sep 17 00:00:00 2001 From: M Nasimul Haque Date: Thu, 26 Sep 2013 00:56:16 +0100 Subject: Add filename option to code-block Prepend the given filename to the code block --- sphinx/directives/code.py | 4 ++++ sphinx/themes/agogo/static/agogo.css_t | 14 ++++++++++++++ sphinx/themes/default/static/default.css_t | 13 +++++++++++++ sphinx/themes/haiku/static/haiku.css_t | 4 ++++ sphinx/themes/nature/static/nature.css_t | 14 ++++++++++++++ sphinx/themes/pyramid/static/pyramid.css_t | 13 +++++++++++++ sphinx/themes/sphinxdoc/static/sphinxdoc.css_t | 14 ++++++++++++++ sphinx/themes/traditional/static/traditional.css_t | 12 ++++++++++++ sphinx/writers/html.py | 3 +++ sphinx/writers/latex.py | 5 +++++ 10 files changed, 96 insertions(+) diff --git a/sphinx/directives/code.py b/sphinx/directives/code.py index 4d43e5ff..8364721e 100644 --- a/sphinx/directives/code.py +++ b/sphinx/directives/code.py @@ -57,6 +57,7 @@ class CodeBlock(Directive): option_spec = { 'linenos': directives.flag, 'emphasize-lines': directives.unchanged_required, + 'filename': directives.unchanged_required, } def run(self): @@ -75,6 +76,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 if hl_lines is not None: literal['highlight_args'] = {'hl_lines': hl_lines} diff --git a/sphinx/themes/agogo/static/agogo.css_t b/sphinx/themes/agogo/static/agogo.css_t index 3fb81178..e22ce16d 100644 --- a/sphinx/themes/agogo/static/agogo.css_t +++ b/sphinx/themes/agogo/static/agogo.css_t @@ -462,3 +462,17 @@ 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-family: monospace; + font-size: small; +} + +div.code-block-filename + pre, +div.code-block-filename + div.highlight, +div.code-block-filename + div.highlight > pre { + margin-top: 0; +} diff --git a/sphinx/themes/default/static/default.css_t b/sphinx/themes/default/static/default.css_t index 5db77108..c1f44477 100644 --- a/sphinx/themes/default/static/default.css_t +++ b/sphinx/themes/default/static/default.css_t @@ -308,3 +308,16 @@ div.viewcode-block:target { border-top: 1px solid #ac9; border-bottom: 1px solid #ac9; } + +div.code-block-filename { + background-color: #1c4e63; + color: #efefef; + padding: 2px 5px; + font-family: monospace; + font-size: small; +} + +div.code-block-filename + pre, +div.code-block-filename + div.highlight > pre { + margin-top: 0; +} diff --git a/sphinx/themes/haiku/static/haiku.css_t b/sphinx/themes/haiku/static/haiku.css_t index 4108125b..c3655dfc 100644 --- a/sphinx/themes/haiku/static/haiku.css_t +++ b/sphinx/themes/haiku/static/haiku.css_t @@ -369,3 +369,7 @@ div.viewcode-block:target { margin: -1px -10px; padding: 0 12px; } + +div.code-block-filename { + font-family: monospace; +} diff --git a/sphinx/themes/nature/static/nature.css_t b/sphinx/themes/nature/static/nature.css_t index 3c492034..8808ee12 100644 --- a/sphinx/themes/nature/static/nature.css_t +++ b/sphinx/themes/nature/static/nature.css_t @@ -243,3 +243,17 @@ 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; + padding: 2px 5px; + font-family: monospace; + font-size: small; +} + +div.code-block-filename + pre, +div.code-block-filename + div.highlight > pre { + margin-top: 0; +} diff --git a/sphinx/themes/pyramid/static/pyramid.css_t b/sphinx/themes/pyramid/static/pyramid.css_t index c4e94908..4e7bacc3 100644 --- a/sphinx/themes/pyramid/static/pyramid.css_t +++ b/sphinx/themes/pyramid/static/pyramid.css_t @@ -340,3 +340,16 @@ tt.xref { font-weight: normal; font-style: normal; } + +div.code-block-filename { + background-color: #ddd; + color: #222; + padding: 2px 5px; + font-family: monospace; + font-size: small; +} + +div.code-block-filename + pre, +div.code-block-filename + div.highlight > pre { + margin-top: 0; +} diff --git a/sphinx/themes/sphinxdoc/static/sphinxdoc.css_t b/sphinx/themes/sphinxdoc/static/sphinxdoc.css_t index af498257..021240d7 100644 --- a/sphinx/themes/sphinxdoc/static/sphinxdoc.css_t +++ b/sphinx/themes/sphinxdoc/static/sphinxdoc.css_t @@ -337,3 +337,17 @@ 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; + padding: 2px 5px; + font-family: monospace; + font-size: small; +} + +div.code-block-filename + pre, +div.code-block-filename + div.highlight > pre { + margin-top: 0; +} diff --git a/sphinx/themes/traditional/static/traditional.css_t b/sphinx/themes/traditional/static/traditional.css_t index 6c6bd5f5..95114473 100644 --- a/sphinx/themes/traditional/static/traditional.css_t +++ b/sphinx/themes/traditional/static/traditional.css_t @@ -702,3 +702,15 @@ div.viewcode-block:target { margin: -1px -10px; padding: 0 10px; } + +div.code-block-filename { + background-color: #cceeff; + padding: 2px 5px; + font-family: monospace; + font-size: small; +} + +div.code-block-filename + pre, +div.code-block-filename + div.highlight > pre { + margin-top: 0; +} diff --git a/sphinx/writers/html.py b/sphinx/writers/html.py index c6747f85..5508d210 100644 --- a/sphinx/writers/html.py +++ b/sphinx/writers/html.py @@ -256,6 +256,9 @@ class HTMLTranslator(BaseTranslator): **highlight_args) starttag = self.starttag(node, 'div', suffix='', CLASS='highlight-%s' % lang) + if node.has_key('filename'): + starttag += '
%s
' % ( + node['filename'],) self.body.append(starttag + highlighted + '\n') raise nodes.SkipNode diff --git a/sphinx/writers/latex.py b/sphinx/writers/latex.py index ce92edfc..df4d5d60 100644 --- a/sphinx/writers/latex.py +++ b/sphinx/writers/latex.py @@ -1333,6 +1333,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, -- cgit v1.2.1 From 10e786edac3809660e9129fe53f5e7e05cc9429e Mon Sep 17 00:00:00 2001 From: guibog Date: Wed, 23 Oct 2013 16:36:45 +0800 Subject: autodoc extension: add autodoc_mock_imports config value --- doc/ext/autodoc.rst | 10 ++++++++++ sphinx/ext/autodoc.py | 32 ++++++++++++++++++++++++++++++++ tests/root/autodoc.txt | 2 ++ tests/root/autodoc_missing_imports.py | 9 +++++++++ tests/root/conf.py | 7 +++++++ 5 files changed, 60 insertions(+) create mode 100644 tests/root/autodoc_missing_imports.py diff --git a/doc/ext/autodoc.rst b/doc/ext/autodoc.rst index c92fe0c4..c37328f5 100644 --- a/doc/ext/autodoc.rst +++ b/doc/ext/autodoc.rst @@ -195,6 +195,10 @@ 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. + .. rst:directive:: autofunction autodata @@ -335,6 +339,12 @@ 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. + Docstring preprocessing ----------------------- diff --git a/sphinx/ext/autodoc.py b/sphinx/ext/autodoc.py index 348c072c..a556edc8 100644 --- a/sphinx/ext/autodoc.py +++ b/sphinx/ext/autodoc.py @@ -70,6 +70,26 @@ class Options(dict): return None +class _MockModule(object): + 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() + + ALL = object() INSTANCEATTR = object() @@ -332,6 +352,8 @@ class Documenter(object): self.modname, '.'.join(self.objpath)) try: dbg('[autodoc] import %s', self.modname) + for modname in self.env.config.autodoc_mock_imports: + self._mock_import(modname) __import__(self.modname) parent = None obj = self.module = sys.modules[self.modname] @@ -361,6 +383,15 @@ class Documenter(object): self.env.note_reread() return False + def _mock_import(self, modname): + if '.' in modname: + pkg, _n, mods = modname.rpartition('.') + self._mock_import(pkg) + mod = _MockModule() + sys.modules[modname] = mod + return mod + + def get_real_modname(self): """Get the real module name of an object to document. @@ -1428,6 +1459,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') diff --git a/tests/root/autodoc.txt b/tests/root/autodoc.txt index d4b3404c..aa0dffba 100644 --- a/tests/root/autodoc.txt +++ b/tests/root/autodoc.txt @@ -45,3 +45,5 @@ Just testing a few autodoc possibilities... :members: ca1, ia1 Specific members (2 total) + +.. automodule:: autodoc_missing_imports diff --git a/tests/root/autodoc_missing_imports.py b/tests/root/autodoc_missing_imports.py new file mode 100644 index 00000000..7a717345 --- /dev/null +++ b/tests/root/autodoc_missing_imports.py @@ -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.""" diff --git a/tests/root/conf.py b/tests/root/conf.py index 8025ba33..215cebf9 100644 --- a/tests/root/conf.py +++ b/tests/root/conf.py @@ -71,6 +71,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') -- cgit v1.2.1 From 0715decc62404efeb34c4fa12b9098b247b316d9 Mon Sep 17 00:00:00 2001 From: tom prince Date: Tue, 29 Oct 2013 16:40:43 -0600 Subject: Make latex commands customizable. --- sphinx/texinputs/Makefile | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/sphinx/texinputs/Makefile b/sphinx/texinputs/Makefile index 6b87ad88..5e6030c0 100644 --- a/sphinx/texinputs/Makefile +++ b/sphinx/texinputs/Makefile @@ -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 -- cgit v1.2.1 From d413fd5731de449c1f69a6c8f4898fd7645fd494 Mon Sep 17 00:00:00 2001 From: Sascha Peilicke Date: Wed, 13 Nov 2013 15:33:25 +0100 Subject: BuildDoc shouldn't fail on Unicode paths. Sub-classes of sphinx.setup_command.BuildDoc may choose to call finalize_options in their run() method again for various reasons. However, currently this fails with py2.7 because of http://bugs.python.org/issue19570. Since it is unlikely that the upstream issue will be solved, a workaround is to re-implement distutils' Command._ensure_stringlike to support Unicode strings. --- sphinx/setup_command.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/sphinx/setup_command.py b/sphinx/setup_command.py index 07cd520c..7999bf59 100644 --- a/sphinx/setup_command.py +++ b/sphinx/setup_command.py @@ -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() -- cgit v1.2.1 From e55efec6d6058d130eac9c4cdb92ddd64335d4c2 Mon Sep 17 00:00:00 2001 From: Georg Brandl Date: Sun, 19 Jan 2014 10:39:23 +0100 Subject: Add "struct" to C++ modifiers. --- sphinx/domains/cpp.py | 1 + 1 file changed, 1 insertion(+) diff --git a/sphinx/domains/cpp.py b/sphinx/domains/cpp.py index 377130b8..d44c9cd7 100644 --- a/sphinx/domains/cpp.py +++ b/sphinx/domains/cpp.py @@ -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',)), -- cgit v1.2.1 From 12c2447b0972fe8bc23ba8132ad5bf13bea5baf7 Mon Sep 17 00:00:00 2001 From: Georg Brandl Date: Sun, 19 Jan 2014 11:14:38 +0100 Subject: Closes #1266: include private modules if includeprivate is true. --- CHANGES | 2 +- sphinx/apidoc.py | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index 3621be4b..36b38e03 100644 --- a/CHANGES +++ b/CHANGES @@ -102,7 +102,7 @@ Bugs fixed * #848: Always take the newest code in incremental rebuilds with the :mod:`sphinx.ext.viewcode` extension. -* #979: Fix exclude handling in ``sphinx-apidoc``. +* #979, #1266: Fix exclude handling in ``sphinx-apidoc``. Documentation ------------- diff --git a/sphinx/apidoc.py b/sphinx/apidoc.py index 4430cdd0..7e95cdae 100644 --- a/sphinx/apidoc.py +++ b/sphinx/apidoc.py @@ -182,6 +182,7 @@ 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): # document only Python module files (that aren't excluded) py_files = sorted(f for f in files @@ -197,7 +198,11 @@ def recurse_tree(rootpath, excludes, opts): continue # remove hidden ('.') and private ('_') directories, as well as # excluded dirs - subs[:] = sorted(sub for sub in subs if sub[0] not in ['.', '_'] + 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: -- cgit v1.2.1 From b06dd5080fc5abd71dc3a427a2bc482cfd7a5733 Mon Sep 17 00:00:00 2001 From: Sascha Peilicke Date: Wed, 13 Nov 2013 15:33:25 +0100 Subject: BuildDoc shouldn't fail on Unicode paths. Sub-classes of sphinx.setup_command.BuildDoc may choose to call finalize_options in their run() method again for various reasons. However, currently this fails with py2.7 because of http://bugs.python.org/issue19570. Since it is unlikely that the upstream issue will be solved, a workaround is to re-implement distutils' Command._ensure_stringlike to support Unicode strings. --- sphinx/setup_command.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/sphinx/setup_command.py b/sphinx/setup_command.py index 07cd520c..7999bf59 100644 --- a/sphinx/setup_command.py +++ b/sphinx/setup_command.py @@ -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() -- cgit v1.2.1 From e3f0fcef07d5fdd1bf4e6201e1c03e8c7a75adb7 Mon Sep 17 00:00:00 2001 From: Georg Brandl Date: Sat, 11 Jan 2014 19:36:05 +0100 Subject: 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! --- doc/Makefile | 166 ++++-------------------------------------- sphinx-build.py | 7 +- sphinx/__init__.py | 6 ++ sphinx/cmdline.py | 36 +++++---- sphinx/make_mode.py | 202 +++++++++++++++++++++++++++++++++++++++++++++++++++ sphinx/quickstart.py | 66 +++++++++++++++++ 6 files changed, 316 insertions(+), 167 deletions(-) create mode 100644 sphinx/make_mode.py diff --git a/doc/Makefile b/doc/Makefile index 831c12c5..d799c365 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 ' where 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 6737d072..54bdb529 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 d41d4424..8a1b97f7 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 e5ad3ab5..f4a09e16 100644 --- a/sphinx/cmdline.py +++ b/sphinx/cmdline.py @@ -42,6 +42,7 @@ General options -d path for the cached environment and doctree files (default: outdir/.doctrees) -j build in parallel with N processes where possible +-M "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 '\ - '.' - 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 .' + 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 00000000..5ef065a5 --- /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', '') + +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 f77e2f22..7ce3ad84 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): -- cgit v1.2.1 From 0b92e30e92f3901b1af3c99cd0f904803a999a30 Mon Sep 17 00:00:00 2001 From: shimizukawa Date: Sat, 18 Jan 2014 22:57:02 +0900 Subject: add missing 'feature added' for non-ASCII filename handling. --- CHANGES | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGES b/CHANGES index 3c0ab53c..443ec774 100644 --- a/CHANGES +++ b/CHANGES @@ -350,6 +350,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 non-ASCII filename handling. + * Other builders: - Added the Docutils-native XML and pseudo-XML builders. See -- cgit v1.2.1 From 27199d51c3c4af6ccba6e102b910f82e4519e417 Mon Sep 17 00:00:00 2001 From: shimizukawa Date: Sun, 19 Jan 2014 00:23:17 +0900 Subject: grammar fix --- CHANGES | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index 443ec774..79de1531 100644 --- a/CHANGES +++ b/CHANGES @@ -350,7 +350,7 @@ 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 non-ASCII filename handling. + - PR#61,#703: Add support for non-ASCII filename handling. * Other builders: -- cgit v1.2.1 From 59b355edaa4f17aff910bf2371526d5ce46fb648 Mon Sep 17 00:00:00 2001 From: Georg Brandl Date: Sun, 19 Jan 2014 07:32:10 +0100 Subject: changelog: bette note about literal_strong --- CHANGES | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/CHANGES b/CHANGES index 33cc66fd..e387ffd5 100644 --- a/CHANGES +++ b/CHANGES @@ -1,16 +1,17 @@ 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. +* 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 ------------ -- cgit v1.2.1 From 600dedfc2f49e158d32c0acf20462b4df78a592f Mon Sep 17 00:00:00 2001 From: Georg Brandl Date: Sun, 19 Jan 2014 09:54:24 +0100 Subject: Closes #848: Always take the newest code in incremental rebuilds with the :mod:`sphinx.ext.viewcode` extension. --- CHANGES | 3 +++ sphinx/ext/viewcode.py | 22 +++++++++++----------- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/CHANGES b/CHANGES index 79de1531..7600958f 100644 --- a/CHANGES +++ b/CHANGES @@ -99,6 +99,9 @@ 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. + Documentation ------------- diff --git a/sphinx/ext/viewcode.py b/sphinx/ext/viewcode.py index 962b543b..36fb47d2 100644 --- a/sphinx/ext/viewcode.py +++ b/sphinx/ext/viewcode.py @@ -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 = [''] -- cgit v1.2.1 From e2159e541dcc9b594aeed4a624df329c2f354545 Mon Sep 17 00:00:00 2001 From: Georg Brandl Date: Sun, 19 Jan 2014 10:13:43 +0100 Subject: Closes #979: Fix exclude handling in ``sphinx-apidoc``. --- CHANGES | 2 ++ sphinx/apidoc.py | 52 +++++++++++++++++++--------------------------------- 2 files changed, 21 insertions(+), 33 deletions(-) diff --git a/CHANGES b/CHANGES index 7600958f..3621be4b 100644 --- a/CHANGES +++ b/CHANGES @@ -102,6 +102,8 @@ Bugs fixed * #848: Always take the newest code in incremental rebuilds with the :mod:`sphinx.ext.viewcode` extension. +* #979: Fix exclude handling in ``sphinx-apidoc``. + Documentation ------------- diff --git a/sphinx/apidoc.py b/sphinx/apidoc.py index c3054662..4430cdd0 100644 --- a/sphinx/apidoc.py +++ b/sphinx/apidoc.py @@ -65,7 +65,7 @@ def write_file(name, text, opts): def format_heading(level, text): """Create a heading of [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] @@ -186,12 +183,10 @@ def recurse_tree(rootpath, excludes, opts): toplevels = [] followlinks = getattr(opts, 'followlinks', 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 +195,10 @@ 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 + subs[:] = sorted(sub for sub in subs if sub[0] not in ['.', '_'] + and not is_excluded(path.join(root, sub), excludes)) if is_pkg: # we are in a package with something to document @@ -225,47 +222,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 [exclude_paths, ...] +usage: %prog [options] -o [exclude_path, ...] Look recursively in for Python modules and packages and create one reST file with automodule directives per package in the . +The 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 +312,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: -- cgit v1.2.1 From 604ea875698727d3c1d83317130af0fff5bb5ab8 Mon Sep 17 00:00:00 2001 From: Georg Brandl Date: Sun, 19 Jan 2014 10:29:06 +0100 Subject: In search word highlighting, dont insist on having div.body. --- sphinx/themes/basic/static/doctools.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sphinx/themes/basic/static/doctools.js b/sphinx/themes/basic/static/doctools.js index 8614442e..2036e5f5 100644 --- a/sphinx/themes/basic/static/doctools.js +++ b/sphinx/themes/basic/static/doctools.js @@ -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'); -- cgit v1.2.1 From 2a033ce3c7397b85cbb12c68046167f1c9c13364 Mon Sep 17 00:00:00 2001 From: Georg Brandl Date: Sun, 19 Jan 2014 10:34:52 +0100 Subject: mock: little changes, changelog and versionadded --- CHANGES | 3 +++ doc/ext/autodoc.rst | 4 ++++ sphinx/ext/autodoc.py | 21 +++++++++++---------- 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/CHANGES b/CHANGES index 2d5c6981..f3f3b1c1 100644 --- a/CHANGES +++ b/CHANGES @@ -18,6 +18,9 @@ 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``. diff --git a/doc/ext/autodoc.rst b/doc/ext/autodoc.rst index c37328f5..94b05423 100644 --- a/doc/ext/autodoc.rst +++ b/doc/ext/autodoc.rst @@ -199,6 +199,8 @@ inserting them into the page source under a suitable :rst:dir:`py:module`, import errors to halt the building process when some external dependencies are not importable at build time. + .. versionadded:: 1.3 + .. rst:directive:: autofunction autodata @@ -345,6 +347,8 @@ There are also new config values that you can set: some external dependencies are not met at build time and break the building process. + .. versionadded:: 1.3 + Docstring preprocessing ----------------------- diff --git a/sphinx/ext/autodoc.py b/sphinx/ext/autodoc.py index 6c13e243..86837ff8 100644 --- a/sphinx/ext/autodoc.py +++ b/sphinx/ext/autodoc.py @@ -71,6 +71,7 @@ class Options(dict): class _MockModule(object): + """Used by autodoc_mock_imports.""" def __init__(self, *args, **kwargs): pass @@ -89,6 +90,14 @@ class _MockModule(object): 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() @@ -353,7 +362,8 @@ class Documenter(object): try: dbg('[autodoc] import %s', self.modname) for modname in self.env.config.autodoc_mock_imports: - self._mock_import(modname) + dbg('[autodoc] adding a mock module %s!', self.modname) + mock_import(modname) __import__(self.modname) parent = None obj = self.module = sys.modules[self.modname] @@ -383,15 +393,6 @@ class Documenter(object): self.env.note_reread() return False - def _mock_import(self, modname): - if '.' in modname: - pkg, _n, mods = modname.rpartition('.') - self._mock_import(pkg) - mod = _MockModule() - sys.modules[modname] = mod - return mod - - def get_real_modname(self): """Get the real module name of an object to document. -- cgit v1.2.1 From f207d092533dcb75024fe9a3e036a72105f27856 Mon Sep 17 00:00:00 2001 From: Georg Brandl Date: Sun, 19 Jan 2014 11:04:12 +0100 Subject: Add :filename: also for literalinclude. Changelog entry. --- CHANGES | 4 ++++ doc/markup/code.rst | 19 +++++++++++++++++++ sphinx/directives/code.py | 6 ++++++ 3 files changed, 29 insertions(+) diff --git a/CHANGES b/CHANGES index f3f3b1c1..42d544b0 100644 --- a/CHANGES +++ b/CHANGES @@ -27,6 +27,10 @@ New features * #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 diff --git a/doc/markup/code.rst b/doc/markup/code.rst index 6e707e00..e9f8f1da 100644 --- a/doc/markup/code.rst +++ b/doc/markup/code.rst @@ -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 diff --git a/sphinx/directives/code.py b/sphinx/directives/code.py index bfe6c48e..6900ea6b 100644 --- a/sphinx/directives/code.py +++ b/sphinx/directives/code.py @@ -115,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): @@ -216,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 -- cgit v1.2.1 From 4d8e32c234bbd1da45f39b94741aef476b377f02 Mon Sep 17 00:00:00 2001 From: Georg Brandl Date: Sun, 19 Jan 2014 11:36:11 +0100 Subject: Closes #1302: Fix regression in :mod:`sphinx.ext.inheritance_diagram` when documenting classes that can't be pickled. --- CHANGES | 3 +++ sphinx/ext/graphviz.py | 3 +++ sphinx/ext/inheritance_diagram.py | 26 ++++++++++++++++---------- 3 files changed, 22 insertions(+), 10 deletions(-) diff --git a/CHANGES b/CHANGES index 36b38e03..13fc1bc4 100644 --- a/CHANGES +++ b/CHANGES @@ -104,6 +104,9 @@ Bugs fixed * #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. + Documentation ------------- diff --git a/sphinx/ext/graphviz.py b/sphinx/ext/graphviz.py index 800e9ca8..32bb96d3 100644 --- a/sphinx/ext/graphviz.py +++ b/sphinx/ext/graphviz.py @@ -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 diff --git a/sphinx/ext/inheritance_diagram.py b/sphinx/ext/inheritance_diagram.py index 2d1d6e30..fd973544 100644 --- a/sphinx/ext/inheritance_diagram.py +++ b/sphinx/ext/inheritance_diagram.py @@ -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))) -- cgit v1.2.1 From 029d8bec8503b5f1da91d86ca13a174d5753a4b9 Mon Sep 17 00:00:00 2001 From: Georg Brandl Date: Sun, 19 Jan 2014 11:38:41 +0100 Subject: Closes #1316: Remove hard-coded ``font-face`` resources from epub theme. --- CHANGES | 2 ++ sphinx/themes/epub/static/epub.css | 7 ++++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/CHANGES b/CHANGES index 13fc1bc4..ee550517 100644 --- a/CHANGES +++ b/CHANGES @@ -107,6 +107,8 @@ Bugs fixed * #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. + Documentation ------------- diff --git a/sphinx/themes/epub/static/epub.css b/sphinx/themes/epub/static/epub.css index 3f4664f6..6c8ff5e7 100644 --- a/sphinx/themes/epub/static/epub.css +++ b/sphinx/themes/epub/static/epub.css @@ -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"); } - +*/ \ No newline at end of file -- cgit v1.2.1 From 2ad1a687bffbc9075ea4df56e638475e748d9af1 Mon Sep 17 00:00:00 2001 From: Georg Brandl Date: Sun, 19 Jan 2014 11:42:44 +0100 Subject: Closes #1329: Fix traceback with empty translation msgstr in .po files. --- CHANGES | 2 ++ sphinx/transforms.py | 10 ++++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index ee550517..3fce72ab 100644 --- a/CHANGES +++ b/CHANGES @@ -109,6 +109,8 @@ Bugs fixed * #1316: Remove hard-coded ``font-face`` resources from epub theme. +* #1329: Fix traceback with empty translation msgstr in .po files. + Documentation ------------- diff --git a/sphinx/transforms.py b/sphinx/transforms.py index 338d4739..14e2c97f 100644 --- a/sphinx/transforms.py +++ b/sphinx/transforms.py @@ -196,7 +196,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 @@ -299,7 +302,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 -- cgit v1.2.1 From 99d7fd4d39fafb1b148ae646d21bfae49bab6606 Mon Sep 17 00:00:00 2001 From: Georg Brandl Date: Sun, 19 Jan 2014 15:39:31 +0100 Subject: Closes #1300: Fix references not working in translated documents in some instances. --- CHANGES | 2 ++ sphinx/transforms.py | 3 +-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index 3fce72ab..3862281c 100644 --- a/CHANGES +++ b/CHANGES @@ -111,6 +111,8 @@ Bugs fixed * #1329: Fix traceback with empty translation msgstr in .po files. +* #1300: Fix references not working in translated documents in some instances. + Documentation ------------- diff --git a/sphinx/transforms.py b/sphinx/transforms.py index 14e2c97f..53bbadb0 100644 --- a/sphinx/transforms.py +++ b/sphinx/transforms.py @@ -242,8 +242,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): -- cgit v1.2.1 From e0e0ddee1cccafa1398c4dd17a410890973eb42b Mon Sep 17 00:00:00 2001 From: Georg Brandl Date: Sun, 19 Jan 2014 15:49:51 +0100 Subject: make mode: add missing build methods. --- sphinx/make_mode.py | 48 +++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 43 insertions(+), 5 deletions(-) diff --git a/sphinx/make_mode.py b/sphinx/make_mode.py index 5ef065a5..c8a2eae5 100644 --- a/sphinx/make_mode.py +++ b/sphinx/make_mode.py @@ -59,6 +59,7 @@ BUILDERS = [ ("", "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)"), ] def build_help(builddir, opts): @@ -133,10 +134,23 @@ def build_epub(builddir, opts): print print 'Build finished. The ePub file is in %s.' % path.join(builddir, 'epub') +def build_latex(builddir, opts): + if run_generic_build('latex', builddir, opts) > 0: + return 1 + print "Build finished; the LaTeX files are in %s." % path.join(builddir, '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(builddir, opts): + if run_generic_build('latex', builddir, opts) > 0: + return 1 + os.system('make -C %s all-pdf' % path.join(builddir, 'latex')) -# latex -# latexpdf -# latexpdfja +def build_latexpdfja(builddir, opts): + if run_generic_build('latex', builddir, opts) > 0: + return 1 + os.system('make -C %s all-pdf-ja' % path.join(builddir, 'latex')) def build_text(builddir, opts): if run_generic_build('text', builddir, opts) > 0: @@ -144,8 +158,18 @@ def build_text(builddir, opts): print print 'Build finished. The text files are in %s.' % path.join(builddir, 'text') -# texinfo -# info +def build_texinfo(builddir, opts): + if run_generic_build('texinfo', builddir, opts) > 0: + return 1 + print "Build finished; the Texinfo files are in %s." % path.join(builddir, '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(builddir, opts): + if run_generic_build('texinfo', builddir, opts) > 0: + return 1 + os.system('make -C %s info' % path.join(builddir, 'texinfo')) def build_gettext(builddir, opts): dtdir = path.join(builddir, 'gettext', '.doctrees') @@ -167,6 +191,20 @@ def build_linkcheck(builddir, opts): 'or in %s.') % path.join(builddir, 'linkcheck', 'output.txt') return res +def build_doctest(builddir, opts): + res = run_generic_build('doctest', builddir, opts) + print ("Testing of doctests in the sources finished, look at the " + "results in %s." % path.join(builddir, 'doctest', 'output.txt')) + return res + +def build_coverage(builddir, opts): + if run_generic_build('coverage', builddir, opts) > 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." % path.join(builddir, 'coverage')) + def build_xml(builddir, opts): if run_generic_build('xml', builddir, opts) > 0: return 1 -- cgit v1.2.1 From aaabdd9b8ba3757180e316098a478cf29d651aa7 Mon Sep 17 00:00:00 2001 From: Georg Brandl Date: Sun, 19 Jan 2014 16:23:23 +0100 Subject: Make mode: refactor using a class and add source dir to the makefile --- doc/Makefile | 18 +-- sphinx/make_mode.py | 370 ++++++++++++++++++++++++++------------------------- sphinx/quickstart.py | 14 +- 3 files changed, 206 insertions(+), 196 deletions(-) diff --git a/doc/Makefile b/doc/Makefile index d799c365..8bc59724 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -5,20 +5,14 @@ SPHINXOPTS = SPHINXBUILD = python ../sphinx-build.py SPHINXPROJ = sphinx +SOURCEDIR = . 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 - +# Has to be explicit, otherwise we don't get "make" without targets right. help: - @$(SPHINXBUILD) -M help "$(BUILDDIR)" $(SPHINXOPTS) $(O) + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) +# 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 $@ "$(BUILDDIR)" $(SPHINXOPTS) $(O) + $(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/sphinx/make_mode.py b/sphinx/make_mode.py index c8a2eae5..24de6b28 100644 --- a/sphinx/make_mode.py +++ b/sphinx/make_mode.py @@ -26,15 +26,6 @@ from sphinx.util.console import bold, blue proj_name = os.getenv('SPHINXPROJ', '') -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"), @@ -62,179 +53,200 @@ BUILDERS = [ ("", "coverage", "to run coverage check of 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') - -def build_latex(builddir, opts): - if run_generic_build('latex', builddir, opts) > 0: - return 1 - print "Build finished; the LaTeX files are in %s." % path.join(builddir, '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(builddir, opts): - if run_generic_build('latex', builddir, opts) > 0: - return 1 - os.system('make -C %s all-pdf' % path.join(builddir, 'latex')) - -def build_latexpdfja(builddir, opts): - if run_generic_build('latex', builddir, opts) > 0: - return 1 - os.system('make -C %s all-pdf-ja' % path.join(builddir, 'latex')) - -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') - -def build_texinfo(builddir, opts): - if run_generic_build('texinfo', builddir, opts) > 0: - return 1 - print "Build finished; the Texinfo files are in %s." % path.join(builddir, '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(builddir, opts): - if run_generic_build('texinfo', builddir, opts) > 0: - return 1 - os.system('make -C %s info' % path.join(builddir, 'texinfo')) - -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_doctest(builddir, opts): - res = run_generic_build('doctest', builddir, opts) - print ("Testing of doctests in the sources finished, look at the " - "results in %s." % path.join(builddir, 'doctest', 'output.txt')) - return res - -def build_coverage(builddir, opts): - if run_generic_build('coverage', builddir, opts) > 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." % path.join(builddir, 'coverage')) - -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) +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) < 2: - print >>sys.stderr, ('Error: at least two arguments (builder, build ' - 'dir) are required.') + 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 run_method in globals(): - return globals()[run_method](args[1], args[2:]) - return run_generic_build(args[0], args[1], args[2:]) + if hasattr(make, run_method): + return getattr(make, run_method)() + return make.run_generic_build(args[0]) diff --git a/sphinx/quickstart.py b/sphinx/quickstart.py index 7ce3ad84..d9449f74 100644 --- a/sphinx/quickstart.py +++ b/sphinx/quickstart.py @@ -839,16 +839,17 @@ if "%%1" == "pseudoxml" ( # This will become the Makefile template for Sphinx 1.5. MAKEFILE_NEW = u'''\ -# Makefile for Sphinx documentation +# 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 +# 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 \ @@ -860,11 +861,14 @@ endif # Has to be explicit, otherwise we don't get "make" without targets right. help: -\t@$(SPHINXBUILD) -M help "$(BUILDDIR)" $(SPHINXOPTS) $(O) +\t@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +# You can add custom targets here. -# Catch-all target using the new "make mode" option. +# 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 $@ "$(BUILDDIR)" $(SPHINXOPTS) $(O) +\t@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) ''' # This will become the make.bat template for Sphinx 1.5. -- cgit v1.2.1 From dbefc55b2fac1e0f531af7d5f4de51aeef65bcf2 Mon Sep 17 00:00:00 2001 From: Georg Brandl Date: Sun, 19 Jan 2014 17:33:55 +0100 Subject: Closes #1283: Fix a bug in the detection of changed files that would try to access doctrees of deleted documents. --- CHANGES | 3 +++ sphinx/builders/__init__.py | 7 +++++++ 2 files changed, 10 insertions(+) diff --git a/CHANGES b/CHANGES index 3862281c..0ff05003 100644 --- a/CHANGES +++ b/CHANGES @@ -113,6 +113,9 @@ Bugs fixed * #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 ------------- diff --git a/sphinx/builders/__init__.py b/sphinx/builders/__init__.py index c153d121..f1280a0b 100644 --- a/sphinx/builders/__init__.py +++ b/sphinx/builders/__init__.py @@ -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): -- cgit v1.2.1 From 2a8cf7c7781a4554adbcb4bae6bec2a40bfc156d Mon Sep 17 00:00:00 2001 From: Georg Brandl Date: Sun, 19 Jan 2014 17:46:06 +0100 Subject: The deprecated config values ``exclude_trees``, ``exclude_dirnames`` and ``unused_docs`` have been removed. --- CHANGES | 3 +++ doc/config.rst | 32 -------------------------------- sphinx/builders/html.py | 5 +---- sphinx/config.py | 4 ---- sphinx/environment.py | 3 --- tests/root/conf.py | 1 - 6 files changed, 4 insertions(+), 44 deletions(-) diff --git a/CHANGES b/CHANGES index 4451a116..402487b2 100644 --- a/CHANGES +++ b/CHANGES @@ -8,6 +8,9 @@ Incompatible changes * 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. diff --git a/doc/config.rst b/doc/config.rst index e4d9feaf..aa34ad40 100644 --- a/doc/config.rst +++ b/doc/config.rst @@ -114,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 diff --git a/sphinx/builders/html.py b/sphinx/builders/html.py index b6ebf926..d715607e 100644 --- a/sphinx/builders/html.py +++ b/sphinx/builders/html.py @@ -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) diff --git a/sphinx/config.py b/sphinx/config.py index df74e914..ace5f2a6 100644 --- a/sphinx/config.py +++ b/sphinx/config.py @@ -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'), diff --git a/sphinx/environment.py b/sphinx/environment.py index a319ef3c..09f76bf2 100644 --- a/sphinx/environment.py +++ b/sphinx/environment.py @@ -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( diff --git a/tests/root/conf.py b/tests/root/conf.py index cf88c2bb..f0d40148 100644 --- a/tests/root/conf.py +++ b/tests/root/conf.py @@ -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' -- cgit v1.2.1