diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 000000000..54e27e201 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,7 @@ +language: python +python: + - "2.7" + - "3.3" +script: make test +install: + - python setup.py -q install diff --git a/AUTHORS b/AUTHORS index a24d6a545..2a9dbbac9 100644 --- a/AUTHORS +++ b/AUTHORS @@ -13,6 +13,7 @@ Other contributors, listed alphabetically, are: * Charles Duffy -- original graphviz extension * Kevin Dunn -- MathJax extension * Josip Dzolonga -- coverage builder +* Hernan Grecco -- search improvements * Horst Gutmann -- internationalization support * Martin Hans -- autodoc improvements * Doug Hellmann -- graphviz improvements diff --git a/CHANGES b/CHANGES index 25bc6daf4..54033b0cb 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,74 @@ Release 1.2 (in development) ============================ +* New locales: #1097: Added Basque locale. + +* Fix text builder did not respect wide/fullwidth characters: + title underline width, table layout width and text wrap width. + +* #1062: sphinx.ext.autodoc use __init__ method signature for class signature. + +* PR#111: Respect add_autodoc_attrgetter() even when inherited-members is set. + Thanks to A. Jesse Jiryu Davis. + +* #1090: Fix gettext does not extract glossary terms. + +* #1070: Avoid un-pickling issues when running Python 3 and the saved + environment was created under Python 2. + +* #1069: Fixed error caused when autodoc would try to format signatures of + "partial" functions without keyword arguments (patch by Artur Gaspar). + +* The :confval:`latex_documents`, :confval:`texinfo_documents`, and + :confval:`man_pages` configuration values will be set to default values based + on the :confval:`master_doc` if not explicitly set in :file:`conf.py`. + Previously, if these values were not set, no output would be genereted by + their respective builders. + +* The :rst:dir:`toctree` directive and the ``toctree()`` template function now + have an ``includehidden`` option that includes hidden toctree entries (bugs + #790 and #1047). A bug in the ``maxdepth`` option for the ``toctree()`` + template function has been fixed (bug #1046). + +* PR#99: Strip down seealso directives to normal admonitions. This removes + their unusual CSS classes (admonition-see-also), inconsistent LaTeX + admonition title ("See Also" instead of "See also"), and spurious indentation + in the text builder. + +* sphinx-build now has a verbose option :option:`-v` which can be + repeated for greater effect. A single occurrance provides a + slightly more verbose output than normal. Two or more occurrences + of this option provides more detailed output which may be useful for + debugging. + +* sphinx-build now provides more specific error messages when called with + invalid options or arguments. + +* sphinx-build now supports the standard :option:`--help` and + :option:`--version` options. + +* #869: sphinx-build now has the option :option:`-T` for printing the full + traceback after an unhandled exception. + +* #976: Fix gettext does not extract index entries. + +* #940: Fix gettext does not extract figure caption. + +* #1067: Improve the ordering of the JavaScript search results: matches in titles + come before matches in full text, and object results are better categorized. + Also implement a pluggable search scorer. + +* Fix text writer can not handle visit_legend for figure directive contents. + +* PR#72: #975: Fix gettext does not extract definition terms before docutils 0.10.0 + +* PR#25: In inheritance diagrams, the first line of the class docstring + is now the tooltip for the class. + +* PR#47: Added :mod:`sphinx.ext.linkcode` extension. + +* PR#75: Added ``--follow-links`` option to sphinx-apidoc. + * PR#45: The linkcheck builder now checks ``#anchor``\ s for existence. * PR#28: Added Hungarian translation. @@ -11,11 +79,55 @@ Release 1.2 (in development) * PR#52: ``special_members`` flag to autodoc now behaves like ``members``. +* #955: Fix i18n transformation. + +* Handle duplicate domain indices in texinfo. + +* PR#74: Fix some Russian translation. + +* PR#97: Fix footnote handling in translated documents. + * Update to jQuery 1.7.1 and Underscore.js 1.3.1. +* #1055: Fix web support with relative path to source directory. -Release 1.1.4 (in development) -============================== +* #1053: The "rightsidebar" and "collapsiblesidebar" HTML theme options now work together. + +* #1015: Stop overriding jQuery contains() in the JavaScript. + +* #1028: Fix line block output in the text builder. + +* #1018: Fix "container" directive handling in the text builder. + +* #1012: Update Estonian translation. + +* #1010: Make pngmath images transparent by default; IE7+ should handle it. + +* #440: Fix coarse timestamp resolution in some filesystem generate wrong outdated file-list. + +* #1008: Fix test failures with Python 3.3. + +* #1029: Fix intersphinx_mapping values are not stable if mapping have plural key/value set with Python 3.3. + +* #920: Rescue PIL packaging issue that allow import Image without PIL namespace. Thanks to Marc Schlaich. + +* #1024: Improve Makefile/make.bat error message if Sphinx is not found. Thanks to anatoly techtonik. + +* #1037: Fix typos in Polish translation. Thanks to Jakub Wilk. + +* #1038: Fix cpp domain parser fails to parse C+11 "static constexpr" declarations. Thanks to Jakub Wilk. + +* #1043: Fix sphinx-quickstart asks again and again Y|N because input() return value with extra '\r' on Python-3.2.0 + Windows. Thanks to Régis Décamps. + +* #1041: Fix cpp domain parser fails to parse a const type with a modifier. + +* #958: Do not preserve ``environment.pickle`` after a failed build. + +* PR#88: Added the "Sphinx Developer's Guide" (:file:`doc/devguide.rst`) + which outlines the basic development process of the Sphinx project. + +* Added the Docutils-native XML and pseudo-XML builders. See + :class:`XMLBuilder` and :class:`PseudoXMLBuilder`. Release 1.1.3 (Mar 10, 2012) diff --git a/EXAMPLES b/EXAMPLES index bb5712d49..3e9e8265f 100644 --- a/EXAMPLES +++ b/EXAMPLES @@ -4,7 +4,7 @@ Projects using Sphinx This is an (incomplete) alphabetic list of projects that use Sphinx or are experimenting with using it for their documentation. If you like to be included, please mail to `the Google group -`_. +`_. I've grouped the list into sections to make it easier to find interesting examples. @@ -70,6 +70,7 @@ Documentation using a customized version of the default theme * Chaco: http://code.enthought.com/projects/chaco/docs/html/ * Djagios: http://djagios.org/ * GetFEM++: http://home.gna.org/getfem/ +* Google or-tools: https://or-tools.googlecode.com/svn/trunk/documentation/user_manual/index.html * GPAW: https://wiki.fysik.dtu.dk/gpaw/ * Grok: http://grok.zope.org/doc/current/ * IFM: http://fluffybunny.memebot.com/ifm-docs/index.html @@ -105,10 +106,11 @@ Documentation using the sphinxdoc theme http://www.tango-controls.org/static/PyTango/latest/doc/html/index.html * Reteisi: http://www.reteisi.org/contents.html * Satchmo: http://www.satchmoproject.com/docs/dev/ -* Sphinx: http://sphinx.pocoo.org/ +* Sphinx: http://sphinx-doc.org/ * Sqlkit: http://sqlkit.argolinux.org/ * Tau: http://www.tango-controls.org/static/tau/latest/doc/html/index.html * Total Open Station: http://tops.berlios.de/ +* Turbulenz: http://docs.turbulenz.com/ * WebFaction: http://docs.webfaction.com/ @@ -128,6 +130,7 @@ Documentation using another builtin theme (agogo) * Sylli: http://sylli.sourceforge.net/ (nature) * libLAS: http://liblas.org/ (nature) +* Valence: http://docs.valence.desire2learn.com/ (haiku) Documentation using a custom theme/integrated in a site @@ -135,7 +138,8 @@ Documentation using a custom theme/integrated in a site * Blender: http://www.blender.org/documentation/250PythonDoc/ * Blinker: http://discorporate.us/projects/Blinker/docs/ -* Classy: classy: http://classy.pocoo.org/ +* Classy: http://classy.pocoo.org/ +* DEAP: http://deap.gel.ulaval.ca/doc/0.8/index.html * Django: http://docs.djangoproject.com/ * e-cidadania: http://e-cidadania.readthedocs.org/en/latest/ * Flask: http://flask.pocoo.org/docs/ @@ -143,13 +147,17 @@ Documentation using a custom theme/integrated in a site * Gameduino: http://excamera.com/sphinx/gameduino/ * GeoServer: http://docs.geoserver.org/ * Glashammer: http://glashammer.org/ +* Istihza (Turkish Python documentation project): http://www.istihza.com/py2/icindekiler_python.html +* MathJax: http://docs.mathjax.org/en/latest/ * MirrorBrain: http://mirrorbrain.org/docs/ * nose: http://somethingaboutorange.com/mrl/projects/nose/ * ObjectListView: http://objectlistview.sourceforge.net/python * Open ERP: http://doc.openerp.com/ +* OpenCV: http://docs.opencv.org/ * OpenLayers: http://docs.openlayers.org/ * PyEphem: http://rhodesmill.org/pyephem/ * German Plone 4.0 user manual: http://www.hasecke.com/plone-benutzerhandbuch/4.0/ +* PSI4: http://sirius.chem.vt.edu/psi4manual/latest/index.html * Pylons: http://pylonshq.com/docs/en/0.9.7/ * PyMOTW: http://www.doughellmann.com/PyMOTW/ * pypol: http://pypol.altervista.org/ (celery) @@ -161,6 +169,7 @@ Documentation using a custom theme/integrated in a site * SQLAlchemy: http://www.sqlalchemy.org/docs/ * tinyTiM: http://tinytim.sourceforge.net/docs/2.0/ * tipfy: http://www.tipfy.org/docs/ +* Ubuntu packaging guide: http://developer.ubuntu.com/packaging/html/ * Werkzeug: http://werkzeug.pocoo.org/docs/ * WFront: http://discorporate.us/projects/WFront/ diff --git a/LICENSE b/LICENSE index 260c20fb1..7aa7620b5 100644 --- a/LICENSE +++ b/LICENSE @@ -1,7 +1,7 @@ License for Sphinx ================== -Copyright (c) 2007-2011 by the Sphinx team (see AUTHORS file). +Copyright (c) 2007-2013 by the Sphinx team (see AUTHORS file). All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/README.rst b/README.rst index 850204d3c..5963a0ae8 100644 --- a/README.rst +++ b/README.rst @@ -21,7 +21,7 @@ After installing:: Then, direct your browser to ``_build/html/index.html``. -Or read them online at . +Or read them online at . Testing diff --git a/distribute_setup.py b/distribute_setup.py index 37117b34e..cebd80b19 100644 --- a/distribute_setup.py +++ b/distribute_setup.py @@ -14,11 +14,14 @@ the appropriate options to ``use_setuptools()``. This file can also be run as a script to install or upgrade setuptools. """ import os +import shutil import sys import time import fnmatch import tempfile import tarfile +import optparse + from distutils import log try: @@ -46,7 +49,7 @@ except ImportError: args = [quote(arg) for arg in args] return os.spawnl(os.P_WAIT, sys.executable, *args) == 0 -DEFAULT_VERSION = "0.6.13" +DEFAULT_VERSION = "0.6.30" DEFAULT_URL = "http://pypi.python.org/packages/source/d/distribute/" SETUPTOOLS_FAKED_VERSION = "0.6c11" @@ -63,7 +66,7 @@ Description: xxx """ % SETUPTOOLS_FAKED_VERSION -def _install(tarball): +def _install(tarball, install_args=()): # extracting the tarball tmpdir = tempfile.mkdtemp() log.warn('Extracting in %s', tmpdir) @@ -81,11 +84,14 @@ def _install(tarball): # installing log.warn('Installing Distribute') - if not _python_cmd('setup.py', 'install'): + if not _python_cmd('setup.py', 'install', *install_args): log.warn('Something went wrong during the installation.') log.warn('See the error message above.') + # exitcode will be 2 + return 2 finally: os.chdir(old_wd) + shutil.rmtree(tmpdir) def _build_egg(egg, tarball, to_dir): @@ -110,6 +116,7 @@ def _build_egg(egg, tarball, to_dir): finally: os.chdir(old_wd) + shutil.rmtree(tmpdir) # returning the result log.warn(egg) if not os.path.exists(egg): @@ -144,7 +151,7 @@ def use_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL, except ImportError: return _do_download(version, download_base, to_dir, download_delay) try: - pkg_resources.require("distribute>="+version) + pkg_resources.require("distribute>=" + version) return except pkg_resources.VersionConflict: e = sys.exc_info()[1] @@ -167,6 +174,7 @@ def use_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL, if not no_fake: _create_fake_setuptools_pkg_info(to_dir) + def download_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir, delay=15): """Download distribute from a specified location and return its filename @@ -203,6 +211,7 @@ def download_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL, dst.close() return os.path.realpath(saveto) + def _no_sandbox(function): def __no_sandbox(*args, **kw): try: @@ -227,6 +236,7 @@ def _no_sandbox(function): return __no_sandbox + def _patch_file(path, content): """Will backup the file then patch it""" existing_content = open(path).read() @@ -245,15 +255,18 @@ def _patch_file(path, content): _patch_file = _no_sandbox(_patch_file) + def _same_content(path, content): return open(path).read() == content + def _rename_path(path): new_name = path + '.OLD.%s' % time.time() - log.warn('Renaming %s into %s', path, new_name) + log.warn('Renaming %s to %s', path, new_name) os.rename(path, new_name) return new_name + def _remove_flat_installation(placeholder): if not os.path.isdir(placeholder): log.warn('Unkown installation at %s', placeholder) @@ -267,7 +280,7 @@ def _remove_flat_installation(placeholder): log.warn('Could not locate setuptools*.egg-info') return - log.warn('Removing elements out of the way...') + log.warn('Moving elements out of the way...') pkg_info = os.path.join(placeholder, file) if os.path.isdir(pkg_info): patched = _patch_egg_dir(pkg_info) @@ -289,11 +302,13 @@ def _remove_flat_installation(placeholder): _remove_flat_installation = _no_sandbox(_remove_flat_installation) + def _after_install(dist): log.warn('After install bootstrap.') placeholder = dist.get_command_obj('install').install_purelib _create_fake_setuptools_pkg_info(placeholder) + def _create_fake_setuptools_pkg_info(placeholder): if not placeholder or not os.path.exists(placeholder): log.warn('Could not find the install location') @@ -307,7 +322,11 @@ def _create_fake_setuptools_pkg_info(placeholder): return log.warn('Creating %s', pkg_info) - f = open(pkg_info, 'w') + try: + f = open(pkg_info, 'w') + except EnvironmentError: + log.warn("Don't have permissions to write %s, skipping", pkg_info) + return try: f.write(SETUPTOOLS_PKG_INFO) finally: @@ -321,7 +340,10 @@ def _create_fake_setuptools_pkg_info(placeholder): finally: f.close() -_create_fake_setuptools_pkg_info = _no_sandbox(_create_fake_setuptools_pkg_info) +_create_fake_setuptools_pkg_info = _no_sandbox( + _create_fake_setuptools_pkg_info +) + def _patch_egg_dir(path): # let's check if it's already patched @@ -343,6 +365,7 @@ def _patch_egg_dir(path): _patch_egg_dir = _no_sandbox(_patch_egg_dir) + def _before_install(): log.warn('Before install bootstrap.') _fake_setuptools() @@ -351,7 +374,7 @@ def _before_install(): def _under_prefix(location): if 'install' not in sys.argv: return True - args = sys.argv[sys.argv.index('install')+1:] + args = sys.argv[sys.argv.index('install') + 1:] for index, arg in enumerate(args): for option in ('--root', '--prefix'): if arg.startswith('%s=' % option): @@ -359,7 +382,7 @@ def _under_prefix(location): return location.startswith(top_dir) elif arg == option: if len(args) > index: - top_dir = args[index+1] + top_dir = args[index + 1] return location.startswith(top_dir) if arg == '--user' and USER_SITE is not None: return location.startswith(USER_SITE) @@ -376,11 +399,14 @@ def _fake_setuptools(): return ws = pkg_resources.working_set try: - setuptools_dist = ws.find(pkg_resources.Requirement.parse('setuptools', - replacement=False)) + setuptools_dist = ws.find( + pkg_resources.Requirement.parse('setuptools', replacement=False) + ) except TypeError: # old distribute API - setuptools_dist = ws.find(pkg_resources.Requirement.parse('setuptools')) + setuptools_dist = ws.find( + pkg_resources.Requirement.parse('setuptools') + ) if setuptools_dist is None: log.warn('No setuptools distribution found') @@ -414,7 +440,7 @@ def _fake_setuptools(): res = _patch_egg_dir(setuptools_location) if not res: return - log.warn('Patched done.') + log.warn('Patching complete.') _relaunch() @@ -422,7 +448,9 @@ def _relaunch(): log.warn('Relaunching...') # we have to relaunch the process # pip marker to avoid a relaunch bug - if sys.argv[:3] == ['-c', 'install', '--single-version-externally-managed']: + _cmd1 = ['-c', 'install', '--single-version-externally-managed'] + _cmd2 = ['-c', 'install', '--record'] + if sys.argv[:3] == _cmd1 or sys.argv[:3] == _cmd2: sys.argv[0] = 'setup.py' args = [sys.executable] + sys.argv sys.exit(subprocess.call(args)) @@ -448,7 +476,7 @@ def _extractall(self, path=".", members=None): # Extract directories with a safe mode. directories.append(tarinfo) tarinfo = copy.copy(tarinfo) - tarinfo.mode = 448 # decimal for oct 0700 + tarinfo.mode = 448 # decimal for oct 0700 self.extract(tarinfo, path) # Reverse sort directories. @@ -475,11 +503,39 @@ def _extractall(self, path=".", members=None): self._dbg(1, "tarfile: %s" % e) -def main(argv, version=DEFAULT_VERSION): - """Install or upgrade setuptools and EasyInstall""" - tarball = download_setuptools() - _install(tarball) +def _build_install_args(options): + """ + Build the arguments to 'python setup.py install' on the distribute package + """ + install_args = [] + if options.user_install: + if sys.version_info < (2, 6): + log.warn("--user requires Python 2.6 or later") + raise SystemExit(1) + install_args.append('--user') + return install_args +def _parse_args(): + """ + Parse the command line for options + """ + parser = optparse.OptionParser() + parser.add_option( + '--user', dest='user_install', action='store_true', default=False, + help='install in user site package (requires Python 2.6 or later)') + parser.add_option( + '--download-base', dest='download_base', metavar="URL", + default=DEFAULT_URL, + help='alternative URL from where to download the distribute package') + options, args = parser.parse_args() + # positional arguments are ignored + return options + +def main(version=DEFAULT_VERSION): + """Install or upgrade setuptools and EasyInstall""" + options = _parse_args() + tarball = download_setuptools(download_base=options.download_base) + return _install(tarball, _build_install_args(options)) if __name__ == '__main__': - main(sys.argv[1:]) + sys.exit(main()) diff --git a/doc/Makefile b/doc/Makefile index 47951316a..831c12c52 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -13,7 +13,8 @@ ALLSPHINXOPTS = -d _build/doctrees $(PAPEROPT_$(PAPER)) \ I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) $(O) . .PHONY: help clean html dirhtml singlehtml text man pickle json htmlhelp \ - qthelp devhelp epub latex latexpdf changes linkcheck doctest + qthelp devhelp epub latex latexpdf changes linkcheck doctest xml \ + pseudoxml help: @echo "Please use \`make ' where is one of" @@ -37,7 +38,7 @@ help: @echo " linkcheck to check all external links for integrity" clean: - -rm -rf _build/* + rm -rf _build/* html: $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) _build/html @@ -147,3 +148,13 @@ info: @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." diff --git a/doc/_static/pocoo.png b/doc/_static/pocoo.png index 297dcd5e0..eeb18eafe 100644 Binary files a/doc/_static/pocoo.png and b/doc/_static/pocoo.png differ diff --git a/doc/_templates/index.html b/doc/_templates/index.html index 34dead7e6..cf2761545 100644 --- a/doc/_templates/index.html +++ b/doc/_templates/index.html @@ -17,25 +17,23 @@ documentation of Python projects, but C/C++ is already supported as well, and it is planned to add special support for other languages as well. Of course, this site is also created from reStructuredText sources using - Sphinx! -

-

- Sphinx is under constant development. The following features are present, - work fine and can be seen “in action” in the Python docs: + Sphinx! The following features should be highlighted:

  • Output formats: HTML (including Windows HTML Help), LaTeX (for - printable PDF versions), manual pages, plain text
  • + printable PDF versions), Texinfo, manual pages, plain text
  • Extensive cross-references: semantic markup and automatic links for functions, classes, citations, glossary terms and similar pieces of information
  • Hierarchical structure: easy definition of a document tree, with automatic links to siblings, parents and children
  • -
  • Automatic indices: general index as well as a module index
  • +
  • Automatic indices: general index as well as a language-specific + module indices
  • Code handling: automatic highlighting using the Pygments highlighter
  • Extensions: automatic testing of code snippets, inclusion of - docstrings from Python modules (API docs), and more
  • + docstrings from Python modules (API docs), and + more

Sphinx uses reStructuredText @@ -44,7 +42,7 @@ suite, the Docutils.

-

Documentation

+

Documentation

@@ -62,9 +60,9 @@

You can also download PDF versions of the Sphinx documentation: - a version generated from + a version generated from the LaTeX Sphinx produces, and - a version generated + a version generated by rst2pdf.

@@ -86,14 +84,4 @@

There is a Japanese translation of this documentation, thanks to Yoshiki Shibukawa.

-

Get Sphinx

-

- Sphinx is available as an easy-installable - package on the Python Package - Index. -

-

The code can be found in a Mercurial repository, at - http://bitbucket.org/birkenfeld/sphinx/.

- {% endblock %} diff --git a/doc/_templates/indexsidebar.html b/doc/_templates/indexsidebar.html index feafd9046..f9aa2abfe 100644 --- a/doc/_templates/indexsidebar.html +++ b/doc/_templates/indexsidebar.html @@ -1,5 +1,5 @@ - +

Download

{% if version.endswith('(hg)') %} @@ -14,17 +14,18 @@

Get Sphinx from the Python Package Index, or install it with:

easy_install -U Sphinx
-

Latest development version docs +

Latest development version docs are also available.

{% endif %}

Questions? Suggestions?

-

Join the Google group:

-
- - +

Join the Google group:

+ + +

or come to the #pocoo channel on FreeNode.

You can also open an issue at the diff --git a/doc/_templates/layout.html b/doc/_templates/layout.html deleted file mode 100644 index 6e609e1a1..000000000 --- a/doc/_templates/layout.html +++ /dev/null @@ -1,23 +0,0 @@ -{% extends "!layout.html" %} - -{% block extrahead %} -{{ super() }} -{%- if not embedded %} - -{%- endif %} -{% endblock %} - -{% block rootrellink %} -

  • Sphinx home | 
  • -
  • Documentation - »
  • -{% endblock %} - -{% block header %} -
    -Sphinx logo -
    -{% endblock %} diff --git a/doc/_themes/sphinx13/layout.html b/doc/_themes/sphinx13/layout.html new file mode 100644 index 000000000..69dd37f77 --- /dev/null +++ b/doc/_themes/sphinx13/layout.html @@ -0,0 +1,78 @@ +{# + sphinxdoc/layout.html + ~~~~~~~~~~~~~~~~~~~~~ + + Sphinx layout template for the sphinxdoc theme. + + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. + :license: BSD, see LICENSE for details. +#} +{%- extends "basic/layout.html" %} + +{# put the sidebar before the body #} +{% block sidebar1 %}{{ sidebar() }}{% endblock %} +{% block sidebar2 %}{% endblock %} + +{% block extrahead %} + +{{ super() }} +{%- if not embedded %} + + +{%- endif %} +{% endblock %} + +{% block rootrellink %} +
  • Sphinx home |
  • +
  • Documentation »
  • +{% endblock %} + +{% block header %} + +{% endblock %} diff --git a/doc/_themes/sphinx13/static/bodybg.png b/doc/_themes/sphinx13/static/bodybg.png new file mode 100644 index 000000000..506b6f908 Binary files /dev/null and b/doc/_themes/sphinx13/static/bodybg.png differ diff --git a/doc/_themes/sphinx13/static/footerbg.png b/doc/_themes/sphinx13/static/footerbg.png new file mode 100644 index 000000000..d1922b446 Binary files /dev/null and b/doc/_themes/sphinx13/static/footerbg.png differ diff --git a/doc/_themes/sphinx13/static/headerbg.png b/doc/_themes/sphinx13/static/headerbg.png new file mode 100644 index 000000000..6d3e1d5e6 Binary files /dev/null and b/doc/_themes/sphinx13/static/headerbg.png differ diff --git a/doc/_themes/sphinx13/static/listitem.png b/doc/_themes/sphinx13/static/listitem.png new file mode 100644 index 000000000..e45715f91 Binary files /dev/null and b/doc/_themes/sphinx13/static/listitem.png differ diff --git a/doc/_themes/sphinx13/static/relbg.png b/doc/_themes/sphinx13/static/relbg.png new file mode 100644 index 000000000..47225851b Binary files /dev/null and b/doc/_themes/sphinx13/static/relbg.png differ diff --git a/doc/_themes/sphinx13/static/sphinx13.css b/doc/_themes/sphinx13/static/sphinx13.css new file mode 100644 index 000000000..bb81b67b5 --- /dev/null +++ b/doc/_themes/sphinx13/static/sphinx13.css @@ -0,0 +1,396 @@ +/* + * sphinx13.css + * ~~~~~~~~~~~~ + * + * Sphinx stylesheet -- sphinx13 theme. + * + * :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +@import url("basic.css"); + +/* -- page layout ----------------------------------------------------------- */ + +body { + font-family: 'Open Sans', 'Lucida Grande', 'Lucida Sans Unicode', 'Geneva', + 'Verdana', sans-serif; + font-size: 14px; + text-align: center; + background-image: url(bodybg.png); + color: black; + padding: 0; + border-right: 1px solid #0a507a; + border-left: 1px solid #0a507a; + + margin: 0 auto; + min-width: 780px; + max-width: 1080px; +} + +.pageheader { + background-image: url(headerbg.png); + text-align: left; + padding: 10px 15px; +} + +.pageheader ul { + float: right; + color: white; + list-style-type: none; + padding-left: 0; + margin-top: 30px; + margin-right: 10px; +} + +.pageheader li { + float: left; + margin: 0 0 0 10px; +} + +.pageheader li a { + border-radius: 1px; + padding: 8px 12px; + color: #f9f9f0; + text-shadow: 0 0 5px rgba(0, 0, 0, 0.5); +} + +.pageheader li a:hover { + background-color: #f9f9f0; + color: #0a507a; + text-shadow: none; +} + +div.document { + background-color: white; + text-align: left; +} + +div.bodywrapper { + margin: 0 240px 0 0; + border-right: 1px solid #0a507a; +} + +div.body { + margin: 0; + padding: 0.5em 20px 20px 20px; +} + +div.related { + font-size: 1em; + color: white; +} + +div.related ul { + background-image: url(relbg.png); + height: 1.9em; + border-top: 1px solid #002e50; + border-bottom: 1px solid #002e50; +} + +div.related ul li { + margin: 0 5px 0 0; + padding: 0; + float: left; +} + +div.related ul li.right { + float: right; + margin-right: 5px; +} + +div.related ul li a { + margin: 0; + padding: 0 5px 0 5px; + line-height: 1.75em; + color: #f9f9f0; + text-shadow: 0px 0px 1px rgba(0, 0, 0, 0.5); +} + +div.related ul li a:hover { + color: white; + /*text-decoration: underline;*/ + text-shadow: 0px 0px 1px rgba(255, 255, 255, 0.5); +} + +div.sphinxsidebarwrapper { + position: relative; + top: 0px; + padding: 0; +} + +div.sphinxsidebar { + margin: 0; + padding: 0 15px 15px 0; + width: 210px; + float: right; + font-size: 1em; + text-align: left; +} + +div.sphinxsidebar .logo { + font-size: 1.8em; + color: #0A507A; + font-weight: 300; + text-align: center; +} + +div.sphinxsidebar .logo img { + vertical-align: middle; +} + +div.sphinxsidebar input { + border: 1px solid #aaa; + font-family: 'Open Sans', 'Lucida Grande', 'Lucida Sans Unicode', 'Geneva', + 'Verdana', sans-serif; + font-size: 1em; +} + +div.sphinxsidebar h3 { + font-size: 1.5em; + border-top: 1px solid #0a507a; + margin-top: 1em; + margin-bottom: 0.5em; + padding-top: 0.5em; +} + +div.sphinxsidebar h4 { + font-size: 1.2em; + margin-bottom: 0; +} + +div.sphinxsidebar h3, div.sphinxsidebar h4 { + margin-right: -15px; + margin-left: -15px; + padding-right: 14px; + padding-left: 14px; + color: #333; + font-weight: 300; + /*text-shadow: 0px 0px 0.5px rgba(0, 0, 0, 0.4);*/ +} + +div.sphinxsidebarwrapper > h3:first-child { + margin-top: 0.5em; + border: none; +} + +div.sphinxsidebar h3 a { + color: #333; +} + +div.sphinxsidebar ul { + color: #444; + margin-top: 7px; + padding: 0; + line-height: 130%; +} + +div.sphinxsidebar ul ul { + margin-left: 20px; + list-style-image: url(listitem.png); +} + +div.footer { + background-image: url(footerbg.png); + color: #ccc; + text-shadow: 0 0 .2px rgba(255, 255, 255, 0.8); + padding: 3px 8px 3px 0; + clear: both; + font-size: 0.8em; + text-align: right; +} + +/* no need to make a visible link to Sphinx on the Sphinx page */ +div.footer a { + color: #ccc; +} + +/* -- body styles ----------------------------------------------------------- */ + +p { + margin: 0.8em 0 0.5em 0; +} + +a { + color: #A2881D; + text-decoration: none; +} + +a:hover { + color: #E1C13F; +} + +div.body a { + text-decoration: underline; +} + +h1 { + margin: 10px 0 0 0; + font-size: 2.4em; + color: #0A507A; + font-weight: 300; +} + +h2 { + margin: 1.em 0 0.2em 0; + font-size: 1.5em; + font-weight: 300; + padding: 0; + color: #174967; +} + +h3 { + margin: 1em 0 -0.3em 0; + font-size: 1.3em; + font-weight: 300; +} + +div.body h1 a, div.body h2 a, div.body h3 a, div.body h4 a, div.body h5 a, div.body h6 a { + text-decoration: none; +} + +div.body h1 a tt, div.body h2 a tt, div.body h3 a tt, div.body h4 a tt, div.body h5 a tt, div.body h6 a tt { + color: #0A507A !important; + font-size: inherit !important; +} + +a.headerlink { + color: #0A507A !important; + font-size: 12px; + margin-left: 6px; + padding: 0 4px 0 4px; + text-decoration: none !important; + float: right; +} + +a.headerlink:hover { + background-color: #ccc; + color: white!important; +} + +cite, code, tt { + font-family: 'Consolas', 'DejaVu Sans Mono', + 'Bitstream Vera Sans Mono', monospace; + font-size: 14px; + letter-spacing: -0.02em; +} + +tt { + background-color: #f2f2f2; + border: 1px solid #ddd; + border-radius: 2px; + color: #333; + padding: 1px; +} + +tt.descname, tt.descclassname, tt.xref { + border: 0; +} + +hr { + border: 1px solid #abc; + margin: 2em; +} + +a tt { + border: 0; + color: #a2881d; +} + +a tt:hover { + color: #e1c13f; +} + +pre { + font-family: 'Consolas', 'DejaVu Sans Mono', + 'Bitstream Vera Sans Mono', monospace; + font-size: 13px; + letter-spacing: 0.015em; + line-height: 120%; + padding: 0.5em; + border: 1px solid #ccc; + border-radius: 2px; + background-color: #f8f8f8; +} + +pre a { + color: inherit; + text-decoration: underline; +} + +td.linenos pre { + padding: 0.5em 0; +} + +div.quotebar { + background-color: #f8f8f8; + max-width: 250px; + float: right; + padding: 0px 7px; + border: 1px solid #ccc; + margin-left: 1em; +} + +div.topic { + background-color: #f8f8f8; +} + +table { + border-collapse: collapse; + margin: 0 -0.5em 0 -0.5em; +} + +table td, table th { + padding: 0.2em 0.5em 0.2em 0.5em; +} + +div.admonition, div.warning { + font-size: 0.9em; + margin: 1em 0 1em 0; + border: 1px solid #86989B; + border-radius: 2px; + background-color: #f7f7f7; + padding: 0; +} + +div.admonition p, div.warning p { + margin: 0.5em 1em 0.5em 1em; + padding: 0; +} + +div.admonition pre, div.warning pre { + margin: 0.4em 1em 0.4em 1em; +} + +div.admonition p.admonition-title, +div.warning p.admonition-title { + margin-top: 1em; + padding-top: 0.5em; + font-weight: bold; +} + +div.warning { + border: 1px solid #940000; +/* background-color: #FFCCCF;*/ +} + +div.warning p.admonition-title { +} + +div.admonition ul, div.admonition ol, +div.warning ul, div.warning ol { + margin: 0.1em 0.5em 0.5em 3em; + padding: 0; +} + +.viewcode-back { + font-family: 'Open Sans', 'Lucida Grande', 'Lucida Sans Unicode', 'Geneva', + 'Verdana', sans-serif; +} + +div.viewcode-block:target { + background-color: #f4debf; + border-top: 1px solid #ac9; + border-bottom: 1px solid #ac9; +} diff --git a/doc/_themes/sphinx13/static/sphinxheader.png b/doc/_themes/sphinx13/static/sphinxheader.png new file mode 100644 index 000000000..2b33f09d9 Binary files /dev/null and b/doc/_themes/sphinx13/static/sphinxheader.png differ diff --git a/doc/_themes/sphinx13/theme.conf b/doc/_themes/sphinx13/theme.conf new file mode 100644 index 000000000..876b19803 --- /dev/null +++ b/doc/_themes/sphinx13/theme.conf @@ -0,0 +1,4 @@ +[theme] +inherit = basic +stylesheet = sphinx13.css +pygments_style = trac diff --git a/doc/builders.rst b/doc/builders.rst index 6600807d3..0075ad810 100644 --- a/doc/builders.rst +++ b/doc/builders.rst @@ -272,6 +272,29 @@ Note that a direct PDF builder using ReportLab is available in `rst2pdf Its name is ``linkcheck``. +.. module:: sphinx.builders.xml +.. class:: XMLBuilder + + This builder produces Docutils-native XML files. The output can be + transformed with standard XML tools such as XSLT processors into arbitrary + final forms. + + Its name is ``xml``. + + .. versionadded:: 1.2 + +.. class:: PseudoXMLBuilder + + This builder is used for debugging the Sphinx/Docutils "Reader to Transform + to Writer" pipeline. It produces compact pretty-printed "pseudo-XML", files + where nesting is indicated by indentation (no end-tags). External + attributes for all elements are output, and internal attributes for any + leftover "pending" elements are also given. + + Its name is ``pseudoxml``. + + .. versionadded:: 1.2 + Built-in Sphinx extensions that offer more builders are: diff --git a/doc/conf.py b/doc/conf.py index 6b547edde..e9998d237 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -13,24 +13,25 @@ templates_path = ['_templates'] exclude_patterns = ['_build'] project = 'Sphinx' -copyright = '2007-2011, Georg Brandl' +copyright = '2007-2013, Georg Brandl' version = sphinx.__released__ release = version show_authors = True -html_theme = 'sphinxdoc' +html_theme = 'sphinx13' +html_theme_path = ['_themes'] modindex_common_prefix = ['sphinx.'] html_static_path = ['_static'] html_sidebars = {'index': ['indexsidebar.html', 'searchbox.html']} html_additional_pages = {'index': 'index.html'} -html_use_opensearch = 'http://sphinx.pocoo.org' +html_use_opensearch = 'http://sphinx-doc.org' htmlhelp_basename = 'Sphinxdoc' epub_theme = 'epub' epub_basename = 'sphinx' epub_author = 'Georg Brandl' -epub_publisher = 'http://sphinx.pocoo.org/' +epub_publisher = 'http://sphinx-doc.org/' epub_scheme = 'url' epub_identifier = epub_publisher epub_pre_files = [('index.html', 'Welcome')] @@ -39,6 +40,7 @@ epub_exclude_files = ['_static/opensearch.xml', '_static/doctools.js', '_static/basic.css', 'search.html', '_static/websupport.js'] epub_fix_images = False epub_max_image_width = 0 +epub_show_urls = 'inline' latex_documents = [('contents', 'sphinx.tex', 'Sphinx Documentation', 'Georg Brandl', 'manual', 1)] diff --git a/doc/config.rst b/doc/config.rst index 6178d459b..34d862e9a 100644 --- a/doc/config.rst +++ b/doc/config.rst @@ -373,6 +373,7 @@ documentation on :ref:`intl` for details. * ``en`` -- English * ``es`` -- Spanish * ``et`` -- Estonian + * ``eu`` -- Basque * ``fa`` -- Iranian * ``fi`` -- Finnish * ``fr`` -- French @@ -383,6 +384,7 @@ documentation on :ref:`intl` for details. * ``ko`` -- Korean * ``lt`` -- Lithuanian * ``lv`` -- Latvian + * ``nb_NO`` -- Norwegian Bokmal * ``ne`` -- Nepali * ``nl`` -- Dutch * ``pl`` -- Polish @@ -759,6 +761,15 @@ that use Sphinx' HTMLWriter class. .. versionadded:: 1.1 +.. confval:: html_search_scorer + + The name of a javascript file (relative to the configuration directory) that + implements a search results scorer. If empty, the default will be used. + + .. XXX describe interface for scorer here + + .. versionadded:: 1.2 + .. confval:: htmlhelp_basename Output file base name for HTML help builder. Default is ``'pydoc'``. @@ -926,6 +937,17 @@ the `Dublin Core metadata `_. .. versionadded:: 1.2 +.. confval:: epub_show_urls + + Control whether to display URL addresses. This is very useful for + readers that have no other means to display the linked URL. The + settings can have the following values: + + * ``'inline'`` -- display URLs inline in parentheses (default) + * ``'no'`` -- do not display URLs + + .. versionadded:: 1.2 + .. _latex-options: @@ -1341,6 +1363,16 @@ Options for the linkcheck builder .. versionadded:: 1.2 +Options for the XML builder +--------------------------- + +.. confval:: xml_pretty + + If True, pretty-print the XML. Default is ``True``. + + .. versionadded:: 1.2 + + .. rubric:: Footnotes .. [1] A note on available globbing syntax: you can use the standard shell diff --git a/doc/contents.rst b/doc/contents.rst index 3bbc28350..5e0ae6c12 100644 --- a/doc/contents.rst +++ b/doc/contents.rst @@ -22,6 +22,7 @@ Sphinx documentation contents faq glossary + devguide changes examples diff --git a/doc/develop.rst b/doc/develop.rst new file mode 100644 index 000000000..4181cde86 --- /dev/null +++ b/doc/develop.rst @@ -0,0 +1,103 @@ +:orphan: + +Sphinx development +================== + +Sphinx is a maintained by a group of volunteers. We value every contribution! + +* The code can be found in a Mercurial repository, at + http://bitbucket.org/birkenfeld/sphinx/. +* Issues and feature requests should be raised in the `tracker + `_. +* The mailing list for development is at `Google Groups + `_. + +For more about our development process and methods, see the :doc:`devguide`. + +Extensions +========== + +The `sphinx-contrib `_ +repository contains many contributed extensions. Some of them have their own +releases on PyPI, others you can install from a checkout. + +This is the current list of contributed extensions in that repository: + +- aafig: render embeded ASCII art as nice images using aafigure_. +- actdiag: embed activity diagrams by using actdiag_ +- adadomain: an extension for Ada support (Sphinx 1.0 needed) +- ansi: parse ANSI color sequences inside documents +- autorun: Execute code in a runblock directive. +- blockdiag: embed block diagrams by using blockdiag_ +- cheeseshop: easily link to PyPI packages +- clearquest: create tables from ClearQuest_ queries. +- coffeedomain: a domain for (auto)documenting CoffeeScript source code. +- context: a builder for ConTeXt. +- doxylink: Link to external Doxygen-generated HTML documentation +- email: obfuscate email addresses +- erlangdomain: an extension for Erlang support (Sphinx 1.0 needed) +- exceltable: embed Excel spreadsheets into documents using exceltable_ +- feed: an extension for creating syndication feeds and time-based overviews + from your site content +- gnuplot: produces images using gnuplot_ language. +- googleanalytics: track html visitors statistics +- googlechart: embed charts by using `Google Chart`_ +- googlemaps: embed maps by using `Google Maps`_ +- httpdomain: a domain for documenting RESTful HTTP APIs. +- hyphenator: client-side hyphenation of HTML using hyphenator_ +- lilypond: an extension inserting music scripts from Lilypond_ in PNG format. +- mscgen: embed mscgen-formatted MSC (Message Sequence Chart)s. +- nicoviceo: embed videos from nicovideo +- nwdiag: embed network diagrams by using nwdiag_ +- omegat: support tools to collaborate with OmegaT_ (Sphinx 1.1 needed) +- osaka: convert standard Japanese doc to Osaka dialect (it is joke extension) +- paverutils: an alternate integration of Sphinx with Paver_. +- phpdomain: an extension for PHP support +- plantuml: embed UML diagram by using PlantUML_ +- rawfiles: copy raw files, like a CNAME. +- requirements: declare requirements wherever you need (e.g. in test + docstrings), mark statuses and collect them in a single list +- rubydomain: an extension for Ruby support (Sphinx 1.0 needed) +- sadisplay: display SqlAlchemy model sadisplay_ +- sdedit: an extension inserting sequence diagram by using Quick Sequence. + Diagram Editor (sdedit_) +- seqdiag: embed sequence diagrams by using seqdiag_ +- slide: embed presentation slides on slideshare_ and other sites. +- swf: embed flash files +- sword: an extension inserting Bible verses from Sword_. +- tikz: draw pictures with the `TikZ/PGF LaTeX package`_. +- traclinks: create TracLinks_ to a Trac_ instance from within Sphinx +- whooshindex: whoosh indexer extension +- youtube: embed videos from YouTube_ +- zopeext: provide an ``autointerface`` directive for using `Zope interfaces`_. + + +See the :ref:`extension tutorial ` on getting started with writing your +own extensions. + + +.. _aafigure: https://launchpad.net/aafigure +.. _gnuplot: http://www.gnuplot.info/ +.. _paver: http://www.blueskyonmars.com/projects/paver/ +.. _Sword: http://www.crosswire.org/sword/ +.. _Lilypond: http://lilypond.org/web/ +.. _sdedit: http://sdedit.sourceforge.net/ +.. _Trac: http://trac.edgewall.org +.. _TracLinks: http://trac.edgewall.org/wiki/TracLinks +.. _OmegaT: http://www.omegat.org/ +.. _PlantUML: http://plantuml.sourceforge.net/ +.. _PyEnchant: http://www.rfk.id.au/software/pyenchant/ +.. _sadisplay: http://bitbucket.org/estin/sadisplay/wiki/Home +.. _blockdiag: http://blockdiag.com/ +.. _seqdiag: http://blockdiag.com/ +.. _actdiag: http://blockdiag.com/ +.. _nwdiag: http://blockdiag.com/ +.. _Google Chart: http://code.google.com/intl/ja/apis/chart/ +.. _Google Maps: http://maps.google.com/ +.. _hyphenator: http://code.google.com/p/hyphenator/ +.. _exceltable: http://packages.python.org/sphinxcontrib-exceltable/ +.. _YouTube: http://www.youtube.com/ +.. _ClearQuest: http://www-01.ibm.com/software/awdtools/clearquest/ +.. _Zope interfaces: http://docs.zope.org/zope.interface/README.html +.. _slideshare: http://www.slideshare.net/ +.. _TikZ/PGF LaTeX package: http://sourceforge.net/projects/pgf/ diff --git a/doc/devguide.rst b/doc/devguide.rst new file mode 100644 index 000000000..ab4bc7409 --- /dev/null +++ b/doc/devguide.rst @@ -0,0 +1,214 @@ +Sphinx Developer's Guide +======================== + +.. topic:: Abstract + + This document describes the development process of Sphinx, a documentation + system used by developers to document systems used by other developers to + develop other systems that may also be documented using Sphinx. + +The Sphinx source code is managed using `Mercurial`_ and is hosted on +`BitBucket`_. + + hg clone https://bitbucket.org/birkenfeld/sphinx + +.. rubric:: Community + +sphinx-users + Mailing list for user support. + +sphinx-dev + Mailing list for development related discussions. + +#pocoo on irc.freenode.net + IRC channel for development questions and user support. + + This channel is shared with other Pocoo projects. Archived logs are + available `here `_. + +.. _`BitBucket`: http://bitbucket.org +.. _`Mercurial`: http://mercurial.selenic.com/ + + +Bug Reports and Feature Requests +-------------------------------- + +If you have encountered a problem with Sphinx or have an idea for a new +feature, please submit it to the `issue tracker`_ on BitBucket or discuss it +on the sphinx-dev mailing list. + +For bug reports, please include the output produced during the build process +and also the log file Sphinx creates after it encounters an un-handled +exception. The location of this file should be shown towards the end of the +error message. + +Including or providing a link to the source files involved may help us fix the +issue. If possible, try to create a minimal project that produces the error +and post that instead. + +.. _`issue tracker`: http://bitbucket.org/birkenfeld/sphinx/issues + + +Contributing to Sphinx +---------------------- + +The recommended way for new contributors to submit code to Sphinx is to fork +the Mercurial repository on BitBucket and then submit a pull request after +committing the changes. The pull request will then need to be approved by one +of the core developers before it is merged into the main repository. + + +Getting Started +~~~~~~~~~~~~~~~ + +These are the basic steps needed to start developing on Sphinx. + +#. Create an account on BitBucket. + +#. Fork the main Sphinx repository (`birkenfeld/sphinx + `_) using the BitBucket interface. + +#. Clone the forked repository to your machine. :: + + hg clone https://bitbucket.org/USERNAME/sphinx-fork + cd sphinx-fork + +#. Checkout the appropriate branch. + + For changes that should be included in the next minor release (namely bug + fixes), use the ``stable`` branch. :: + + hg checkout stable + + For new features or other substantial changes that should wait until the + next major release, use the ``default`` branch. + +#. Setup your Python environment. :: + + virtualenv ~/sphinxenv + . ~/sphinxenv/bin/activate + pip install -e . + +#. Hack, hack, hack. + + For tips on working with the code, see the `Coding Guide`_. + +#. Test, test, test. + + Run the unit tests:: + + pip install nose + make test + + Build the documentation and check the output for different builders:: + + cd docs + make clean html text man info latexpdf + + Run the unit tests under different Python environments using + :program:`tox`:: + + pip install tox + tox -v + + Add a new unit test in the ``tests`` directory if you can. + + For bug fixes, first add a test that fails without your changes and passes + after they are applied. + +#. Commit your changes. :: + + hg commit -m 'Add useful new feature that does this.' + + BitBucket recognizes `certain phrases`__ that can be used to automatically + update the issue tracker. + + For example:: + + hg commit -m 'Closes #42: Fix invalid markup in docstring of Foo.bar.' + + would close issue #42. + + __ https://confluence.atlassian.com/display/BITBUCKET/Automatically+Resolving+Issues+when+Users+Push+Code + +#. Push changes to your forked repository on BitBucket. :: + + hg push + +#. Submit a pull request from your repository to ``birkenfeld/sphinx`` using + the BitBucket interface. + +#. Wait for a core developer to review your changes. + + +Core Developers +~~~~~~~~~~~~~~~ + +The core developers of Sphinx have write access to the main repository. They +can commit changes, accept/reject pull requests, and manage items on the issue +tracker. + +You do not need to be a core developer or have write access to be involved in +the development of Sphinx. You can submit patches or create pull requests +from forked repositories and have a core developer add the changes for you. + +The following are some general guidelines for core developers: + +* Questionable or extensive changes should be submitted as a pull request + instead of being committed directly to the main repository. The pull + request should be reviewed by another core developer before it is merged. + +* Trivial changes can be committed directly but be sure to keep the repository + in a good working state and that all tests pass before pushing your changes. + +* When committing code written by someone else, please attribute the original + author in the commit message and any relevant :file:`CHANGES` entry. + +* Using Mercurial named branches other than ``default`` and ``stable`` is not + encouraged. + + +Coding Guide +------------ + +* Try to use the same code style as used in the rest of the project. See the + `Pocoo Styleguide`__ for more information. + + __ http://flask.pocoo.org/docs/styleguide/ + +* For non-trivial changes, please update the :file:`CHANGES` file. If your + changes alter existing behavior, please document this. + +* New features should be documented. Include examples and use cases where + appropriate. If possible, include a sample that is displayed in the + generated output. + +* When adding a new configuration variable, be sure to document it and update + :file:`sphinx/quickstart.py`. + +* Use the included :program:`utils/check_sources.py` script to check for + common formatting issues (trailing whitespace, lengthy lines, etc). + +* Add appropriate unit tests. + + +Debugging Tips +~~~~~~~~~~~~~~ + +* Delete the build cache before building documents if you make changes in the + code by running the command ``make clean`` or using the + :option:`sphinx-build -E` option. + +* Use the :option:`sphinx-build -P` option to run Pdb on exceptions. + +* Use ``node.pformat()`` and ``node.asdom().toxml()`` to generate a printable + representation of the document structure. + +* Set the configuration variable :confval:`keep_warnings` to True so warnings + will be displayed in the generated output. + +* Set the configuration variable :confval:`nitpicky` to True so that Sphinx + will complain about references without a known target. + +* Set the debugging options in the `Docutils configuration file + `_. diff --git a/doc/domains.rst b/doc/domains.rst index 3d52db3fd..bd99a4c5e 100644 --- a/doc/domains.rst +++ b/doc/domains.rst @@ -812,7 +812,15 @@ More domains ------------ The sphinx-contrib_ repository contains more domains available as extensions; -currently Ada, Erlang, HTTP, PHP, and Ruby domains. +currently Ada, CoffeeScript_, Erlang_, HTTP_, Jinja_, PHP_, Ruby, and Scala_ +domains. .. _sphinx-contrib: https://bitbucket.org/birkenfeld/sphinx-contrib/ + +.. _CoffeeScript: http://pypi.python.org/pypi/sphinxcontrib-coffee +.. _Erlang: http://pypi.python.org/pypi/sphinxcontrib-erlangdomain +.. _HTTP: http://pypi.python.org/pypi/sphinxcontrib-httpdomain +.. _Jinja: http://pypi.python.org/pypi/sphinxcontrib-jinjadomain +.. _Scala: http://pypi.python.org/pypi/sphinxcontrib-scaladomain +.. _PHP: http://pypi.python.org/pypi/sphinxcontrib-phpdomain diff --git a/doc/ext/linkcode.rst b/doc/ext/linkcode.rst new file mode 100644 index 000000000..a69a5b1c5 --- /dev/null +++ b/doc/ext/linkcode.rst @@ -0,0 +1,46 @@ +:mod:`sphinx.ext.linkcode` -- Add external links to source code +=============================================================== + +.. module:: sphinx.ext.linkcode + :synopsis: Add external links to source code. +.. moduleauthor:: Pauli Virtanen + +.. versionadded:: 1.2 + +This extension looks at your object descriptions (``.. class::``, +``.. function::`` etc.) and adds external links to code hosted +somewhere on the web. The intent is similar to the +``sphinx.ext.viewcode`` extension, but assumes the source code can be +found somewhere on the Internet. + +In your configuration, you need to specify a :confval:`linkcode_resolve` +function that returns an URL based on the object. + +.. confval:: linkcode_resolve + + This is a function ``linkcode_resolve(domain, info)``, + which should return the URL to source code corresponding to + the object in given domain with given information. + + The function should return ``None`` if no link is to be added. + + The argument ``domain`` specifies the language domain the object is + in. ``info`` is a dictionary with the following keys guaranteed to + be present (dependent on the domain): + + - ``py``: ``module`` (name of the module), ``fullname`` (name of the object) + - ``c``: ``names`` (list of names for the object) + - ``cpp``: ``names`` (list of names for the object) + - ``javascript``: ``object`` (name of the object), ``fullname`` (name of the item) + + Example: + + .. code-block:: python + + def linkcode_resolve(domain, info): + if domain != 'py': + return None + if not info['module']: + return None + filename = info['module'].replace('.', '/') + return "http://somesite/sourcerepo/%s.py" % filename diff --git a/doc/ext/math.rst b/doc/ext/math.rst index 3652b55e8..91376d15d 100644 --- a/doc/ext/math.rst +++ b/doc/ext/math.rst @@ -148,19 +148,12 @@ built: .. confval:: pngmath_dvipng_args Additional arguments to give to dvipng, as a list. The default value is - ``['-gamma 1.5', '-D 110']`` which makes the image a bit darker and larger - then it is by default. + ``['-gamma', '1.5', '-D', '110', '-bg', 'Transparent']`` which makes the + image a bit darker and larger then it is by default, and produces PNGs with a + transparent background. - An arguments you might want to add here is e.g. ``'-bg Transparent'``, - which produces PNGs with a transparent background. This is not enabled by - default because some Internet Explorer versions don't like transparent PNGs. - - .. note:: - - When you "add" an argument, you need to reproduce the default arguments if - you want to keep them; that is, like this:: - - pngmath_dvipng_args = ['-gamma 1.5', '-D 110', '-bg Transparent'] + .. versionchanged:: 1.2 + Now includes ``-bg Transparent`` by default. .. confval:: pngmath_use_preview diff --git a/doc/extensions.rst b/doc/extensions.rst index b93974486..07bc7fe4b 100644 --- a/doc/extensions.rst +++ b/doc/extensions.rst @@ -53,6 +53,7 @@ These extensions are built in and can be activated by respective entries in the ext/todo ext/extlinks ext/viewcode + ext/linkcode ext/oldcmarkup diff --git a/doc/faq.rst b/doc/faq.rst index bf2327d70..1d9487377 100644 --- a/doc/faq.rst +++ b/doc/faq.rst @@ -36,6 +36,13 @@ How do I... still need to mark up classes and such, but the headings and code examples come through cleanly. +... create HTML slides from Sphinx documents? + See the "Hieroglyph" package at http://github.com/nyergler/hieroglyph. + +For many more extensions and other contributed stuff, see the sphinx-contrib_ +repository. + +.. _sphinx-contrib: https://bitbucket.org/birkenfeld/sphinx-contrib/ .. _usingwith: diff --git a/doc/install.rst b/doc/install.rst new file mode 100644 index 000000000..3af60dad5 --- /dev/null +++ b/doc/install.rst @@ -0,0 +1,166 @@ +:orphan: + +Installing Sphinx +================== + +Sphinx is written by Python, you need to install Python and Sphinx. + +Sphinx package is available as a package on the `Python Package Index +`_. + +You can also download a snapshot from the Mercurial development repository: + +* as a `.tar.bz2 `_ + file or +* as a `.zip `_ file + +There is introductions for each environments: + +.. contents:: + :depth: 1 + :local: + :backlinks: none + + +Install by your own +-------------------- + +If you use system installed Python or build your own Python, you can +use that python to install Sphinx. The actual command list is same as +these install. + +* `Install easy_install command`_ +* `Install Sphinx`_ + + +Debian/Ubuntu: Install Sphinx using packaging system +----------------------------------------------------- + +You may install using this command if you use Debian/Ubuntu. + +.. code-block:: bash + + $ aptitude install python-sphinx + + +Mac OS X: Install Sphinx using MacPorts +---------------------------------------- + +If you use Mac OS X `MacPorts `_ , use this +command to install all software. + +.. code-block:: bash + + $ sudo port install py27-sphinx + +However, the execution path is not added, use select command to use +Python2.7 as default. + +.. code-block:: bash + + $ sudo port select --set python python27 + $ sudo port select --set sphinx py27-sphinx + +Type :command:`which sphinx-quickstart` to check the installation. + + +Windows: Install Python and Sphinx +----------------------------------- + +Intall Python +^^^^^^^^^^^^^^ + +Almost every Windows user do not have Python, we begin Python +installation. If you already install python, please skip this section. + +Go to http://python.org . This site is a headquarter of the +Python. Look at Left sidebar and "Quick Links", Click "Windows +Installer" to download. + +.. image:: pythonorg.jpg + +.. note:: + + Currently, Python has two version, 2.X and 3.X. Sphinx-1.2 can + run under Python-2.5, 2.6, 2.7, 3.1, 3.2, 3.3. + You may get some advice from ML or other places. + + This chapter assumes Python-2.7. + + +Follow the normal Windows installer, the Python install will be completed. + +.. image:: installpython.jpg + +After installation, you have better to add PATH to the Environment +Variable in order to run Python from Command Prompt. + +* Right-Click the My Computer Icon and open Property Dialog +* Click Environment Variable button under detail tab +* Edit and add the path to the system variables PATH + +Add these variables. This is for Python-2.7. If you use another version +of Python, change the "27" number. Add these pathes separeted by ";". + +.. list-table:: Adding PATH + :widths: 10 40 + :header-rows: 1 + + * - PATH + - description + * - C:\\Python27 + - Folder which includes Python Command + * - C:\\Python27\\Scripts + - Folder which includes easy_install (described later) or sphinx commands + +Run **Command Prompt** or enter ``cmd`` to the "search program and +files" text box. After command prompt window appear, type +``python[Enter]``. If you can get installed python version and prompt +about ``>>>``, the Python installation is succeeded. Enter ``Ctrl+Z`` +key to quit. + + +Install easy_install command +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Python has very useful :command:`easy_install` command which install 3rd +party library. + +* http://pypi.python.org/pypi/distribute + +easy_install downloads and install software which you want to need by only +one command. + + +Save http://distribute.org/distribute_setup.py link by Right-click. +Some browsers can download just open the URL. +If you can read the file iteslf, calm down, Right-click and choose "Save". + +After download, invoke command prompt, go to the distribute_setup.py saved +directory and run this command: + +.. code-block:: bat + + C:\> python distribute_setup.py + +Now :command:`easy_insall` command is installed. OK, Let's go to the Sphinx +install! + + +Install Sphinx +^^^^^^^^^^^^^^^ + +If you finshed easy_install install, for the rest is just a moment. +Type this line. + +.. code-block:: bat + + C:\> easy_install sphinx + +After installation, type :command:`sphinx-quickstart` on the command +prompt. If you get interactive messages which starts with +``Welcome to the Sphinx quickstart utility.``, +installation is succeeded. Quit by hitting ``Ctrl+C``. + +That it. Install is over. Let's go to :doc:`tutorial` to make Sphinx project. + diff --git a/doc/installpython.jpg b/doc/installpython.jpg new file mode 100644 index 000000000..b0e458e40 Binary files /dev/null and b/doc/installpython.jpg differ diff --git a/doc/intro.rst b/doc/intro.rst index 5d76dd29c..4d052c818 100644 --- a/doc/intro.rst +++ b/doc/intro.rst @@ -50,19 +50,15 @@ See the :ref:`pertinent section in the FAQ list `. Prerequisites ------------- -Sphinx needs at least **Python 2.4** or **Python 3.1** to run, as well as the +Sphinx needs at least **Python 2.5** or **Python 3.1** to run, as well as the docutils_ and Jinja2_ libraries. Sphinx should work with docutils version 0.7 or some (not broken) SVN trunk snapshot. If you like to have source code highlighting support, you must also install the Pygments_ library. -If you use **Python 2.4** you also need uuid_. - .. _reStructuredText: http://docutils.sf.net/rst.html .. _docutils: http://docutils.sf.net/ .. _Jinja2: http://jinja.pocoo.org/ .. _Pygments: http://pygments.org/ -.. The given homepage is only a directory listing so I'm using the pypi site. -.. _uuid: http://pypi.python.org/pypi/uuid/ Usage diff --git a/doc/invocation.rst b/doc/invocation.rst index 2c69d32f9..4cfa48433 100644 --- a/doc/invocation.rst +++ b/doc/invocation.rst @@ -59,6 +59,13 @@ The :program:`sphinx-build` script has several options: **linkcheck** Check the integrity of all external links. + **xml** + Build Docutils-native XML files. + + **pseudoxml** + Build compact pretty-printed "pseudo-XML" files displaying the + internal structure of the intermediate document trees. + See :ref:`builders` for a list of all builders shipped with Sphinx. Extensions can add their own builders. @@ -131,6 +138,13 @@ The :program:`sphinx-build` script has several options: Do not emit colored output. (On Windows, colored output is disabled in any case.) +.. option:: -v + + Increase verbosity. This option can be given up to three times to get more + debug output. It implies :option:`-T`. + + .. versionadded:: 1.2 + .. option:: -q Do not output anything on standard output, only write warnings and errors to @@ -150,11 +164,24 @@ The :program:`sphinx-build` script has several options: Turn warnings into errors. This means that the build stops at the first warning and ``sphinx-build`` exits with exit status 1. +.. option:: -T + + Display the full traceback when an unhandled exception occurs. Otherwise, + only a summary is displayed and the traceback information is saved to a file + for further analysis. + + .. versionadded:: 1.2 + .. option:: -P (Useful for debugging only.) Run the Python debugger, :mod:`pdb`, if an unhandled exception occurs while building. +.. option:: -h, --help, --version + + Display usage summary or Sphinx version. + + .. versionadded:: 1.2 You can also give one or more filenames on the command line after the source and build directories. Sphinx will then try to build only these output files (and @@ -227,6 +254,17 @@ The :program:`sphinx-apidoc` script has several options: This sets the maximum depth of the table of contents, if one is generated. +.. option:: -l, --follow-links + + This option makes sphinx-apidoc follow symbolic links when recursing the + filesystem to discover packages and modules. You may need it if you want + to generate documentation from a source directory managed by + `collective.recipe.omelette + `_. + By default, symbolic links are skipped. + + .. versionadded:: 1.2 + .. option:: -T, --no-toc This prevents the generation of a table-of-contents file ``modules.rst``. diff --git a/doc/man/sphinx-build.rst b/doc/man/sphinx-build.rst index b7212a84b..0a5d4abb9 100644 --- a/doc/man/sphinx-build.rst +++ b/doc/man/sphinx-build.rst @@ -64,6 +64,13 @@ linkcheck pickle / json Generates serialized HTML files for use in web applications. +xml + Generates Docutils-native XML files. + +pseudoxml + Generates compact pretty-printed "pseudo-XML" files displaying the + internal structure of the intermediate document trees. + Options ------- diff --git a/doc/markup/misc.rst b/doc/markup/misc.rst index 3a2ffa32e..f5eaac9ce 100644 --- a/doc/markup/misc.rst +++ b/doc/markup/misc.rst @@ -182,13 +182,6 @@ Including content based on tags The format of the current builder (``html``, ``latex`` or ``text``) is always set as a tag. - .. note:: - - Due to docutils' specifics of parsing of directive content, you cannot put - a section with the same level as the main document heading inside an - ``only`` directive. Such sections will appear to be ignored in the parsed - document. - .. versionadded:: 0.6 diff --git a/doc/markup/toctree.rst b/doc/markup/toctree.rst index 625fbb611..fe27e019d 100644 --- a/doc/markup/toctree.rst +++ b/doc/markup/toctree.rst @@ -126,6 +126,18 @@ tables of contents. The ``toctree`` directive is the central element. intend to insert these links yourself, in a different style, or in the HTML sidebar. + In cases where you want to have only one top-level toctree and hide all other + lower level toctrees you can add the "includehidden" option to the top-level + toctree entry:: + + .. toctree:: + :includehidden: + + doc_1 + doc_2 + + All other toctree entries can then be eliminated by the "hidden" option. + In the end, all documents in the :term:`source directory` (or subdirectories) must occur in some ``toctree`` directive; Sphinx will emit a warning if it finds a file that is not included, because that means that this file will not @@ -150,6 +162,8 @@ tables of contents. The ``toctree`` directive is the central element. .. versionchanged:: 1.1 Added numeric argument to "numbered". + .. versionchanged:: 1.2 + Added "includehidden" option. Special names ------------- diff --git a/doc/pythonorg.jpg b/doc/pythonorg.jpg new file mode 100644 index 000000000..83b54df0b Binary files /dev/null and b/doc/pythonorg.jpg differ diff --git a/doc/templating.rst b/doc/templating.rst index 05a1346c0..b9dfc683b 100644 --- a/doc/templating.rst +++ b/doc/templating.rst @@ -391,3 +391,6 @@ are in HTML form), these variables are also available: * ``titles_only`` (false by default): if true, put only toplevel document titles in the tree + + * ``includehidden`` (false by default): if true, the TOC tree will also + contain hidden entries. diff --git a/doc/theming.rst b/doc/theming.rst index 334f6ffe7..0375bc710 100644 --- a/doc/theming.rst +++ b/doc/theming.rst @@ -111,8 +111,7 @@ These themes are: - **collapsiblesidebar** (true or false): Add an *experimental* JavaScript snippet that makes the sidebar collapsible via a button on its side. - *Doesn't work together with "rightsidebar" or "stickysidebar".* Defaults to - false. + *Doesn't work with "stickysidebar".* Defaults to false. - **externalrefs** (true or false): Display external links differently from internal links. Defaults to false. diff --git a/doc/tutorial.rst b/doc/tutorial.rst index b0e1d4869..9fea11dbe 100644 --- a/doc/tutorial.rst +++ b/doc/tutorial.rst @@ -13,10 +13,10 @@ the described task. Setting up the documentation sources ------------------------------------ -The root directory of a documentation collection is called the :term:`source -directory`. This directory also contains the Sphinx configuration file -:file:`conf.py`, where you can configure all aspects of how Sphinx reads your -sources and builds your documentation. [#]_ +The root directory of a Sphinx collection of reStructuredText document sources +is called the :term:`source directory`. This directory also contains the Sphinx +configuration file :file:`conf.py`, where you can configure all aspects of how +Sphinx reads your sources and builds your documentation. [#]_ Sphinx comes with a script called :program:`sphinx-quickstart` that sets up a source directory and creates a default :file:`conf.py` with the most useful diff --git a/setup.cfg b/setup.cfg index 525e24ea3..5dac60b4d 100644 --- a/setup.cfg +++ b/setup.cfg @@ -4,6 +4,7 @@ tag_date = true [aliases] release = egg_info -RDb '' +upload = upload --sign --identity=36580288 [extract_messages] mapping_file = babel.cfg diff --git a/setup.py b/setup.py index ca41aa431..03f8e8e14 100644 --- a/setup.py +++ b/setup.py @@ -46,26 +46,20 @@ A development egg can be found `here requires = ['Pygments>=1.2', 'Jinja2>=2.3', 'docutils>=0.7'] -if sys.version_info < (2, 4): - print('ERROR: Sphinx requires at least Python 2.4 to run.') - sys.exit(1) +if sys.version_info[:3] >= (3, 3, 0): + requires[2] = 'docutils>=0.10' if sys.version_info < (2, 5): - # Python 2.4's distutils doesn't automatically install an egg-info, - # so an existing docutils install won't be detected -- in that case, - # remove the dependency from setup.py - try: - import docutils - if int(docutils.__version__[2]) < 4: - raise ValueError('docutils not recent enough') - except: - pass - else: - del requires[-1] - - # The uuid module is new in the stdlib in 2.5 - requires.append('uuid>=1.30') + print('ERROR: Sphinx requires at least Python 2.5 to run.') + sys.exit(1) +# tell distribute to use 2to3 with our own fixers +extra = {} +if sys.version_info >= (3, 0): + extra.update( + use_2to3=True, + use_2to3_fixers=['custom_fixers'] + ) # Provide a "compile_catalog" command that also creates the translated # JavaScript files if Babel is available. @@ -164,7 +158,7 @@ else: setup( name='Sphinx', version=sphinx.__version__, - url='http://sphinx.pocoo.org/', + url='http://sphinx-doc.org/', download_url='http://pypi.python.org/pypi/Sphinx', license='BSD', author='Georg Brandl', @@ -203,6 +197,5 @@ setup( }, install_requires=requires, cmdclass=cmdclass, - use_2to3=True, - use_2to3_fixers=['custom_fixers'], + **extra ) diff --git a/sphinx-apidoc.py b/sphinx-apidoc.py index 9cafb497d..31e57487f 100755 --- a/sphinx-apidoc.py +++ b/sphinx-apidoc.py @@ -4,7 +4,7 @@ Sphinx - Python documentation toolchain ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx-autogen.py b/sphinx-autogen.py index b1e467e77..baf3ed65e 100755 --- a/sphinx-autogen.py +++ b/sphinx-autogen.py @@ -4,7 +4,7 @@ Sphinx - Python documentation toolchain ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx-build.py b/sphinx-build.py index 70822d732..6737d0729 100755 --- a/sphinx-build.py +++ b/sphinx-build.py @@ -4,7 +4,7 @@ Sphinx - Python documentation toolchain ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx-quickstart.py b/sphinx-quickstart.py index 5d7c15443..0ae67adfc 100755 --- a/sphinx-quickstart.py +++ b/sphinx-quickstart.py @@ -4,7 +4,7 @@ Sphinx - Python documentation toolchain ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/__init__.py b/sphinx/__init__.py index e1ffc2ed6..0c68ad322 100644 --- a/sphinx/__init__.py +++ b/sphinx/__init__.py @@ -5,7 +5,7 @@ The Sphinx documentation toolchain. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ @@ -38,11 +38,20 @@ if '+' in __version__ or 'pre' in __version__: def main(argv=sys.argv): """Sphinx build "main" command-line entry.""" - if sys.version_info[:3] < (2, 4, 0): + if sys.version_info[:3] < (2, 5, 0): sys.stderr.write('Error: Sphinx requires at least ' - 'Python 2.4 to run.\n') + 'Python 2.5 to run.\n') return 1 - + if sys.version_info[:3] >= (3, 3, 0): + try: + import docutils + x, y = docutils.__version__.split('.')[:2] + if (int(x), int(y)) < (0, 10): + sys.stderr.write('Error: Sphinx requires at least ' + 'Docutils 0.10 for Python 3.3 and above.\n') + return 1 + except Exception: + pass try: from sphinx import cmdline except ImportError: diff --git a/sphinx/addnodes.py b/sphinx/addnodes.py index 94f1d615f..d8dca2ce4 100644 --- a/sphinx/addnodes.py +++ b/sphinx/addnodes.py @@ -5,7 +5,7 @@ Additional docutils nodes. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/apidoc.py b/sphinx/apidoc.py index ec1a8a33f..151608288 100644 --- a/sphinx/apidoc.py +++ b/sphinx/apidoc.py @@ -11,7 +11,7 @@ Copyright 2008 Société des arts technologiques (SAT), http://www.sat.qc.ca/ - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ import os @@ -157,7 +157,8 @@ def recurse_tree(rootpath, excludes, opts): root_package = None toplevels = [] - for root, subs, files in os.walk(rootpath): + followlinks = getattr(opts, 'followlinks', False) + for root, subs, files in os.walk(rootpath, followlinks=followlinks): if is_excluded(root, excludes): del subs[:] continue @@ -246,6 +247,10 @@ Note: By default this script will not overwrite already created files.""") '(default: 4)', type='int', default=4) parser.add_option('-f', '--force', action='store_true', dest='force', help='Overwrite all files') + parser.add_option('-l', '--follow-links', action='store_true', + dest='followlinks', default=False, + help='Follow symbolic links. Powerful when combined ' + 'with collective.recipe.omelette.') parser.add_option('-n', '--dry-run', action='store_true', dest='dryrun', help='Run the script without creating files') parser.add_option('-T', '--no-toc', action='store_true', dest='notoc', diff --git a/sphinx/application.py b/sphinx/application.py index bfb39a70f..c2ebb535e 100644 --- a/sphinx/application.py +++ b/sphinx/application.py @@ -7,10 +7,11 @@ Gracefully adapted from the TextPress system by Armin. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ +import os import sys import types import posixpath @@ -34,7 +35,7 @@ from sphinx.environment import BuildEnvironment, SphinxStandaloneReader from sphinx.util import pycompat # imported for side-effects from sphinx.util.tags import Tags from sphinx.util.osutil import ENOENT -from sphinx.util.console import bold +from sphinx.util.console import bold, lightgray, darkgray # List of all known core events. Maps name to arguments description. @@ -60,7 +61,8 @@ class Sphinx(object): def __init__(self, srcdir, confdir, outdir, doctreedir, buildername, confoverrides=None, status=sys.stdout, warning=sys.stderr, - freshenv=False, warningiserror=False, tags=None): + freshenv=False, warningiserror=False, tags=None, verbosity=0): + self.verbosity = verbosity self.next_listener_id = 0 self._extensions = {} self._listeners = {} @@ -194,6 +196,8 @@ class Sphinx(object): self.builder = builderclass(self) self.emit('builder-inited') + # ---- main "build" method ------------------------------------------------- + def build(self, force_all=False, filenames=None): try: if force_all: @@ -203,12 +207,29 @@ class Sphinx(object): else: self.builder.build_update() except Exception, err: + # delete the saved env to force a fresh build next time + envfile = path.join(self.doctreedir, ENV_PICKLE_FILENAME) + if path.isfile(envfile): + os.unlink(envfile) self.emit('build-finished', err) raise else: self.emit('build-finished', None) self.builder.cleanup() + # ---- logging handling ---------------------------------------------------- + + def _log(self, message, wfile, nonl=False): + try: + wfile.write(message) + except UnicodeEncodeError: + encoding = getattr(wfile, 'encoding', 'ascii') or 'ascii' + wfile.write(message.encode(encoding, 'replace')) + if not nonl: + wfile.write('\n') + if hasattr(wfile, 'flush'): + wfile.flush() + def warn(self, message, location=None, prefix='WARNING: '): if isinstance(location, tuple): docname, lineno = location @@ -221,26 +242,37 @@ class Sphinx(object): if self.warningiserror: raise SphinxWarning(warntext) self._warncount += 1 - try: - self._warning.write(warntext) - except UnicodeEncodeError: - encoding = getattr(self._warning, 'encoding', 'ascii') or 'ascii' - self._warning.write(warntext.encode(encoding, 'replace')) + self._log(warntext, self._warning, True) def info(self, message='', nonl=False): - try: - self._status.write(message) - except UnicodeEncodeError: - encoding = getattr(self._status, 'encoding', 'ascii') or 'ascii' - self._status.write(message.encode(encoding, 'replace')) - if not nonl: - self._status.write('\n') - self._status.flush() + self._log(message, self._status, nonl) - # general extensibility interface + def verbose(self, message, *args, **kwargs): + if self.verbosity < 1: + return + if args or kwargs: + message = message % (args or kwargs) + self._log(message, self._status) + + def debug(self, message, *args, **kwargs): + if self.verbosity < 2: + return + if args or kwargs: + message = message % (args or kwargs) + self._log(darkgray(message), self._status) + + def debug2(self, message, *args, **kwargs): + if self.verbosity < 3: + return + if args or kwargs: + message = message % (args or kwargs) + self._log(lightgray(message), self._status) + + # ---- general extensibility interface ------------------------------------- def setup_extension(self, extension): """Import and setup a Sphinx extension module. No-op if called twice.""" + self.debug('[app] setting up extension: %r', extension) if extension in self._extensions: return try: @@ -301,13 +333,17 @@ class Sphinx(object): else: self._listeners[event][listener_id] = callback self.next_listener_id += 1 + self.debug('[app] connecting event %r: %r [id=%s]', + event, callback, listener_id) return listener_id def disconnect(self, listener_id): + self.debug('[app] disconnecting event: [id=%s]', listener_id) for event in self._listeners.itervalues(): event.pop(listener_id, None) def emit(self, event, *args): + self.debug2('[app] emitting event: %r%s', event, repr(args)[:100]) results = [] if event in self._listeners: for _, callback in self._listeners[event].iteritems(): @@ -323,6 +359,7 @@ class Sphinx(object): # registering addon parts def add_builder(self, builder): + self.debug('[app] adding builder: %r', builder) if not hasattr(builder, 'name'): raise ExtensionError('Builder class %s has no "name" attribute' % builder) @@ -337,6 +374,7 @@ class Sphinx(object): self.builderclasses[builder.name] = builder def add_config_value(self, name, default, rebuild): + self.debug('[app] adding config value: %r', (name, default, rebuild)) if name in self.config.values: raise ExtensionError('Config value %r already present' % name) if rebuild in (False, True): @@ -344,11 +382,13 @@ class Sphinx(object): self.config.values[name] = (default, rebuild) def add_event(self, name): + self.debug('[app] adding event: %r', name) if name in self._events: raise ExtensionError('Event %r already present' % name) self._events[name] = '' def add_node(self, node, **kwds): + self.debug('[app] adding node: %r', (node, kwds)) nodes._add_node_class_names([node.__name__]) for key, val in kwds.iteritems(): try: @@ -388,44 +428,54 @@ class Sphinx(object): return obj def add_directive(self, name, obj, content=None, arguments=None, **options): + self.debug('[app] adding directive: %r', + (name, obj, content, arguments, options)) directives.register_directive( name, self._directive_helper(obj, content, arguments, **options)) def add_role(self, name, role): + self.debug('[app] adding role: %r', (name, role)) roles.register_local_role(name, role) def add_generic_role(self, name, nodeclass): # don't use roles.register_generic_role because it uses # register_canonical_role + self.debug('[app] adding generic role: %r', (name, nodeclass)) role = roles.GenericRole(name, nodeclass) roles.register_local_role(name, role) def add_domain(self, domain): + self.debug('[app] adding domain: %r', domain) if domain.name in self.domains: raise ExtensionError('domain %s already registered' % domain.name) self.domains[domain.name] = domain def override_domain(self, domain): + self.debug('[app] overriding domain: %r', domain) if domain.name not in self.domains: raise ExtensionError('domain %s not yet registered' % domain.name) if not issubclass(domain, self.domains[domain.name]): - raise ExtensionError('new domain not a subclass of registered ' + raise ExtensionError('new domain not a subclass of registered %s ' 'domain' % domain.name) self.domains[domain.name] = domain def add_directive_to_domain(self, domain, name, obj, content=None, arguments=None, **options): + self.debug('[app] adding directive to domain: %r', + (domain, name, obj, content, arguments, options)) if domain not in self.domains: raise ExtensionError('domain %s not yet registered' % domain) self.domains[domain].directives[name] = \ self._directive_helper(obj, content, arguments, **options) def add_role_to_domain(self, domain, name, role): + self.debug('[app] adding role to domain: %r', (domain, name, role)) if domain not in self.domains: raise ExtensionError('domain %s not yet registered' % domain) self.domains[domain].roles[name] = role def add_index_to_domain(self, domain, index): + self.debug('[app] adding index to domain: %r', (domain, index)) if domain not in self.domains: raise ExtensionError('domain %s not yet registered' % domain) self.domains[domain].indices.append(index) @@ -433,6 +483,9 @@ class Sphinx(object): def add_object_type(self, directivename, rolename, indextemplate='', parse_node=None, ref_nodeclass=None, objname='', doc_field_types=[]): + self.debug('[app] adding object type: %r', + (directivename, rolename, indextemplate, parse_node, + ref_nodeclass, objname, doc_field_types)) StandardDomain.object_types[directivename] = \ ObjType(objname or directivename, rolename) # create a subclass of GenericObject as the new directive @@ -449,6 +502,9 @@ class Sphinx(object): def add_crossref_type(self, directivename, rolename, indextemplate='', ref_nodeclass=None, objname=''): + self.debug('[app] adding crossref type: %r', + (directivename, rolename, indextemplate, ref_nodeclass, + objname)) StandardDomain.object_types[directivename] = \ ObjType(objname or directivename, rolename) # create a subclass of Target as the new directive @@ -459,9 +515,11 @@ class Sphinx(object): StandardDomain.roles[rolename] = XRefRole(innernodeclass=ref_nodeclass) def add_transform(self, transform): + self.debug('[app] adding transform: %r', transform) SphinxStandaloneReader.transforms.append(transform) def add_javascript(self, filename): + self.debug('[app] adding javascript: %r', filename) from sphinx.builders.html import StandaloneHTMLBuilder if '://' in filename: StandaloneHTMLBuilder.script_files.append(filename) @@ -470,6 +528,7 @@ class Sphinx(object): posixpath.join('_static', filename)) def add_stylesheet(self, filename): + self.debug('[app] adding stylesheet: %r', filename) from sphinx.builders.html import StandaloneHTMLBuilder if '://' in filename: StandaloneHTMLBuilder.css_files.append(filename) @@ -478,21 +537,25 @@ class Sphinx(object): posixpath.join('_static', filename)) def add_lexer(self, alias, lexer): + self.debug('[app] adding lexer: %r', (alias, lexer)) from sphinx.highlighting import lexers if lexers is None: return lexers[alias] = lexer def add_autodocumenter(self, cls): + self.debug('[app] adding autodocumenter: %r', cls) from sphinx.ext import autodoc autodoc.add_documenter(cls) self.add_directive('auto' + cls.objtype, autodoc.AutoDirective) def add_autodoc_attrgetter(self, type, getter): + self.debug('[app] adding autodoc attrgetter: %r', (type, getter)) from sphinx.ext import autodoc autodoc.AutoDirective._special_attrgetters[type] = getter def add_search_language(self, cls): + self.debug('[app] adding search language: %r', cls) from sphinx.search import languages, SearchLanguage assert isinstance(cls, SearchLanguage) languages[cls.lang] = cls diff --git a/sphinx/builders/__init__.py b/sphinx/builders/__init__.py index 5240a1c73..97932c4c7 100644 --- a/sphinx/builders/__init__.py +++ b/sphinx/builders/__init__.py @@ -5,7 +5,7 @@ Builder superclass for all builders. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ @@ -119,9 +119,13 @@ class Builder(object): summary = bold(summary) for item in iterable: l += 1 - self.info(term_width_line('%s[%3d%%] %s' % - (summary, 100*l/length, - colorfunc(item))), nonl=1) + s = '%s[%3d%%] %s' % (summary, 100*l/length, + colorfunc(item)) + if self.app.verbosity: + s += '\n' + else: + s = term_width_line(s) + self.info(s, nonl=1) yield item if l > 0: self.info() @@ -334,4 +338,6 @@ BUILTIN_BUILDERS = { 'linkcheck': ('linkcheck', 'CheckExternalLinksBuilder'), 'websupport': ('websupport', 'WebSupportBuilder'), 'gettext': ('gettext', 'MessageCatalogBuilder'), + 'xml': ('xml', 'XMLBuilder'), + 'pseudoxml': ('xml', 'PseudoXMLBuilder'), } diff --git a/sphinx/builders/changes.py b/sphinx/builders/changes.py index 22fcab869..05e7166ed 100644 --- a/sphinx/builders/changes.py +++ b/sphinx/builders/changes.py @@ -5,7 +5,7 @@ Changelog builder. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/builders/devhelp.py b/sphinx/builders/devhelp.py index 62bd22377..81d2e6cee 100644 --- a/sphinx/builders/devhelp.py +++ b/sphinx/builders/devhelp.py @@ -7,9 +7,10 @@ .. _Devhelp: http://live.gnome.org/devhelp - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ +from __future__ import absolute_import import re from os import path diff --git a/sphinx/builders/epub.py b/sphinx/builders/epub.py index b4c3b2776..6803753bf 100644 --- a/sphinx/builders/epub.py +++ b/sphinx/builders/epub.py @@ -6,7 +6,7 @@ Build epub files. Originally derived from qthelp.py. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ @@ -30,7 +30,7 @@ from docutils import nodes from sphinx import addnodes from sphinx.builders.html import StandaloneHTMLBuilder -from sphinx.util.osutil import ensuredir, EEXIST +from sphinx.util.osutil import ensuredir, copyfile, EEXIST from sphinx.util.smartypants import sphinx_smarty_pants as ssp from sphinx.util.console import brown @@ -281,8 +281,11 @@ class EpubBuilder(StandaloneHTMLBuilder): newids.append(self.fix_fragment('', id)) node.attributes['ids'] = newids - def add_visible_links(self, tree): - """Append visible link targets after external links.""" + def add_visible_links(self, tree, show_urls='inline'): + """Append visible link targets after external links""" + if show_urls == 'no': + return + for node in tree.traverse(nodes.reference): uri = node.get('refuri', '') if (uri.startswith('http:') or uri.startswith('https:') or @@ -290,9 +293,10 @@ class EpubBuilder(StandaloneHTMLBuilder): uri = _link_target_template % {'uri': uri} if uri: idx = node.parent.index(node) + 1 - link = nodes.inline(uri, uri) - link['classes'].append(_css_link_target_class) - node.parent.insert(idx, link) + if show_urls == 'inline': + link = nodes.inline(uri, uri) + link['classes'].append(_css_link_target_class) + node.parent.insert(idx, link) def write_doc(self, docname, doctree): """Write one document file. @@ -301,7 +305,7 @@ class EpubBuilder(StandaloneHTMLBuilder): and to add visible external links. """ self.fix_ids(doctree) - self.add_visible_links(doctree) + self.add_visible_links(doctree, self.config.epub_show_urls) return StandaloneHTMLBuilder.write_doc(self, docname, doctree) def fix_genindex(self, tree): @@ -662,7 +666,12 @@ class EpubBuilder(StandaloneHTMLBuilder): zipfile.ZIP_STORED) for file in projectfiles: fp = path.join(outdir, file) - if isinstance(fp, unicode): - fp = fp.encode(sys.getfilesystemencoding()) + if sys.version_info < (2, 6): + # When zipile.ZipFile.write call with unicode filename, ZipFile + # encode filename to 'utf-8' (only after Python-2.6). + if isinstance(file, unicode): + # OEBPS Container Format (OCF) 2.0.1 specification require + # "File Names MUST be UTF-8 encoded". + file = file.encode('utf-8') epub.write(fp, file, zipfile.ZIP_DEFLATED) epub.close() diff --git a/sphinx/builders/gettext.py b/sphinx/builders/gettext.py index a5f71a5f6..7a6e1abe6 100644 --- a/sphinx/builders/gettext.py +++ b/sphinx/builders/gettext.py @@ -5,7 +5,7 @@ The MessageCatalogBuilder class. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ @@ -15,9 +15,11 @@ from datetime import datetime from collections import defaultdict from sphinx.builders import Builder -from sphinx.util.nodes import extract_messages -from sphinx.util.osutil import SEP, safe_relpath, ensuredir, find_catalog +from sphinx.util import split_index_msg +from sphinx.util.nodes import extract_messages, traverse_translatable_index +from sphinx.util.osutil import safe_relpath, ensuredir, find_catalog from sphinx.util.console import darkgreen +from sphinx.locale import pairindextypes POHEADER = ur""" # SOME DESCRIPTIVE TITLE. @@ -82,6 +84,16 @@ class I18nBuilder(Builder): for node, msg in extract_messages(doctree): catalog.add(msg, node) + # Extract translatable messages from index entries. + for node, entries in traverse_translatable_index(doctree): + for typ, msg, tid, main in entries: + for m in split_index_msg(typ, msg): + if typ == 'pair' and m in pairindextypes.values(): + # avoid built-in translated message was incorporated + # in 'sphinx.util.nodes.process_index_entry' + continue + catalog.add(m, node) + class MessageCatalogBuilder(I18nBuilder): """ diff --git a/sphinx/builders/html.py b/sphinx/builders/html.py index f5218673f..1d1dfa799 100644 --- a/sphinx/builders/html.py +++ b/sphinx/builders/html.py @@ -5,7 +5,7 @@ Several HTML builders. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ @@ -53,6 +53,23 @@ INVENTORY_FILENAME = 'objects.inv' LAST_BUILD_FILENAME = 'last_build' +def get_object_hash(obj): + """ + In python3.3, unicode(dict_instance) retun another string per process. + get_object_hash(dict_instance) return same hash for same dict_instance. + """ + if isinstance(obj, dict): + return get_object_hash(list(obj.items())) + + elif isinstance(obj, (list, tuple)): + obj = sorted(get_object_hash(o) for o in obj) + + else: # int or other objects + pass + + return md5(unicode(obj).encode('utf8')).hexdigest() + + class StandaloneHTMLBuilder(Builder): """ Builds standalone HTML docs. @@ -156,9 +173,8 @@ class StandaloneHTMLBuilder(Builder): cfgdict = dict((name, self.config[name]) for (name, desc) in self.config.values.iteritems() if desc[1] == 'html') - self.config_hash = md5(unicode(cfgdict).encode('utf-8')).hexdigest() - self.tags_hash = md5(unicode(sorted(self.tags)).encode('utf-8')) \ - .hexdigest() + self.config_hash = get_object_hash(cfgdict) + self.tags_hash = get_object_hash(sorted(self.tags)) old_config_hash = old_tags_hash = '' try: fp = open(path.join(self.outdir, '.buildinfo')) @@ -240,7 +256,8 @@ class StandaloneHTMLBuilder(Builder): if not lang or lang not in languages: lang = 'en' self.indexer = IndexBuilder(self.env, lang, - self.config.html_search_options) + self.config.html_search_options, + self.config.html_search_scorer) self.load_indexer(docnames) self.docwriter = HTMLWriter(self) @@ -653,6 +670,8 @@ class StandaloneHTMLBuilder(Builder): self.indexer.feed(pagename, title, doctree) def _get_local_toctree(self, docname, collapse=True, **kwds): + if 'includehidden' not in kwds: + kwds['includehidden'] = False return self.render_partial(self.env.get_toctree_for( docname, self, collapse, **kwds))['fragment'] diff --git a/sphinx/builders/htmlhelp.py b/sphinx/builders/htmlhelp.py index a1dcef239..605012f8f 100644 --- a/sphinx/builders/htmlhelp.py +++ b/sphinx/builders/htmlhelp.py @@ -6,7 +6,7 @@ Build HTML help support files. Parts adapted from Python's Doc/tools/prechm.py. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/builders/latex.py b/sphinx/builders/latex.py index 3369338c2..dcc3b3603 100644 --- a/sphinx/builders/latex.py +++ b/sphinx/builders/latex.py @@ -5,7 +5,7 @@ LaTeX builder. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/builders/linkcheck.py b/sphinx/builders/linkcheck.py index a8adcdac7..c567401c5 100644 --- a/sphinx/builders/linkcheck.py +++ b/sphinx/builders/linkcheck.py @@ -5,7 +5,7 @@ The CheckExternalLinksBuilder class. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ @@ -102,7 +102,8 @@ class CheckExternalLinksBuilder(Builder): def check(): # check for various conditions without bothering the network - if len(uri) == 0 or uri[0] == '#' or uri[0:7] == 'mailto:' or uri[0:4] == 'ftp:': + if len(uri) == 0 or uri[0] == '#' or \ + uri[0:7] == 'mailto:' or uri[0:4] == 'ftp:': return 'unchecked', '' elif not (uri[0:5] == 'http:' or uri[0:6] == 'https:'): return 'local', '' diff --git a/sphinx/builders/manpage.py b/sphinx/builders/manpage.py index 93b56a01c..32a097574 100644 --- a/sphinx/builders/manpage.py +++ b/sphinx/builders/manpage.py @@ -5,7 +5,7 @@ Manual pages builder. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/builders/qthelp.py b/sphinx/builders/qthelp.py index 5e5deaf1a..ce07315db 100644 --- a/sphinx/builders/qthelp.py +++ b/sphinx/builders/qthelp.py @@ -5,7 +5,7 @@ Build input files for the Qt collection generator. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/builders/texinfo.py b/sphinx/builders/texinfo.py index 535c527e0..a606fc6cc 100644 --- a/sphinx/builders/texinfo.py +++ b/sphinx/builders/texinfo.py @@ -5,7 +5,7 @@ Texinfo builder. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ @@ -72,9 +72,9 @@ uninstall-info: info \t-$(TEXI2PDF) '$<' clean: -\t-rm -f *.info *.pdf *.txt *.html -\t-rm -f *.log *.ind *.aux *.toc *.syn *.idx *.out *.ilg *.pla *.ky *.pg -\t-rm -f *.vr *.tp *.fn *.fns *.def *.defs *.cp *.cps *.ge *.ges *.mo +\trm -f *.info *.pdf *.txt *.html +\trm -f *.log *.ind *.aux *.toc *.syn *.idx *.out *.ilg *.pla *.ky *.pg +\trm -f *.vr *.tp *.fn *.fns *.def *.defs *.cp *.cps *.ge *.ges *.mo .PHONY: all info plaintext html pdf install-info uninstall-info clean ''' diff --git a/sphinx/builders/text.py b/sphinx/builders/text.py index 40fd3d791..98148a8c6 100644 --- a/sphinx/builders/text.py +++ b/sphinx/builders/text.py @@ -5,7 +5,7 @@ Plain-text Sphinx builder. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/builders/websupport.py b/sphinx/builders/websupport.py index b77573095..d8238bb46 100644 --- a/sphinx/builders/websupport.py +++ b/sphinx/builders/websupport.py @@ -5,7 +5,7 @@ Builder for the web support package. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/builders/xml.py b/sphinx/builders/xml.py new file mode 100644 index 000000000..ec411a79d --- /dev/null +++ b/sphinx/builders/xml.py @@ -0,0 +1,98 @@ +# -*- coding: utf-8 -*- +""" + sphinx.builders.xml + ~~~~~~~~~~~~~~~~~~~ + + Docutils-native XML and pseudo-XML builders. + + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" + +import codecs +from os import path + +from docutils import nodes +from docutils.io import StringOutput + +from sphinx.builders import Builder +from sphinx.util.osutil import ensuredir, os_path +from sphinx.writers.xml import XMLWriter, PseudoXMLWriter + +class XMLBuilder(Builder): + """ + Builds Docutils-native XML. + """ + name = 'xml' + format = 'xml' + out_suffix = '.xml' + + _writer_class = XMLWriter + + def init(self): + pass + + def get_outdated_docs(self): + for docname in self.env.found_docs: + if docname not in self.env.all_docs: + yield docname + continue + targetname = self.env.doc2path(docname, self.outdir, + self.out_suffix) + try: + targetmtime = path.getmtime(targetname) + except Exception: + targetmtime = 0 + try: + srcmtime = path.getmtime(self.env.doc2path(docname)) + if srcmtime > targetmtime: + yield docname + except EnvironmentError: + # source doesn't exist anymore + pass + + def get_target_uri(self, docname, typ=None): + return '' + + def prepare_writing(self, docnames): + self.writer = self._writer_class(self) + + def write_doc(self, docname, doctree): + # work around multiple string % tuple issues in docutils; + # replace tuples in attribute values with lists + doctree = doctree.deepcopy() + for node in doctree.traverse(nodes.Element): + for att, value in node.attributes.items(): + if isinstance(value, tuple): + node.attributes[att] = list(value) + value = node.attributes[att] + if isinstance(value, list): + for i, val in enumerate(value): + if isinstance(val, tuple): + value[i] = list(val) + destination = StringOutput(encoding='utf-8') + self.writer.write(doctree, destination) + outfilename = path.join(self.outdir, os_path(docname) + self.out_suffix) + ensuredir(path.dirname(outfilename)) + try: + f = codecs.open(outfilename, 'w', 'utf-8') + try: + f.write(self.writer.output) + finally: + f.close() + except (IOError, OSError), err: + self.warn("error writing file %s: %s" % (outfilename, err)) + + def finish(self): + pass + + +class PseudoXMLBuilder(XMLBuilder): + """ + Builds pseudo-XML for display purposes. + """ + name = 'pseudoxml' + format = 'pseudoxml' + out_suffix = '.pseudoxml' + + _writer_class = PseudoXMLWriter diff --git a/sphinx/cmdline.py b/sphinx/cmdline.py index 9fc213716..13bd2e9f4 100644 --- a/sphinx/cmdline.py +++ b/sphinx/cmdline.py @@ -5,7 +5,7 @@ sphinx-build command-line handling. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ @@ -22,9 +22,17 @@ from sphinx.errors import SphinxError from sphinx.application import Sphinx from sphinx.util import Tee, format_exception_cut_frames, save_traceback from sphinx.util.console import red, nocolor, color_terminal +from sphinx.util.osutil import fs_encoding from sphinx.util.pycompat import terminal_safe, bytes +def abspath(pathdir): + pathdir = path.abspath(pathdir) + if isinstance(pathdir, bytes): + pathdir = pathdir.decode(fs_encoding) + return pathdir + + def usage(argv, msg=None): if msg: print >>sys.stderr, msg @@ -32,29 +40,47 @@ def usage(argv, msg=None): print >>sys.stderr, """\ Sphinx v%s Usage: %s [options] sourcedir outdir [filenames...] -Options: -b -- builder to use; default is html - -a -- write all files; default is to only write \ -new and changed files - -E -- don't use a saved environment, always read all files - -t -- include "only" blocks with - -d -- path for the cached environment and doctree files - (default: outdir/.doctrees) - -c -- path where configuration file (conf.py) is located + +General options +^^^^^^^^^^^^^^^ +-b builder to use; default is html +-a write all files; default is to only write new and changed files +-E don't use a saved environment, always read all files +-d path for the cached environment and doctree files + (default: outdir/.doctrees) + +Build configuration options +^^^^^^^^^^^^^^^^^^^^^^^^^^^ +-c path where configuration file (conf.py) is located (default: same as sourcedir) - -C -- use no config file at all, only -D options - -D -- override a setting in configuration - -A -- pass a value into the templates, for HTML builder - -n -- nit-picky mode, warn about all missing references - -N -- do not do colored output - -q -- no output on stdout, just warnings on stderr - -Q -- no output at all, not even warnings - -w -- write warnings (and errors) to given file - -W -- turn warnings into errors - -P -- run Pdb on exception -Modi: +-C use no config file at all, only -D options +-D override a setting in configuration file +-t define tag: include "only" blocks with +-A pass a value into the templates, for HTML builder +-n nit-picky mode, warn about all missing references + +Console output options +^^^^^^^^^^^^^^^^^^^^^^ +-v increase verbosity (can be repeated) +-q no output on stdout, just warnings on stderr +-Q no output at all, not even warnings +-w write warnings (and errors) to given file +-W turn warnings into errors +-T show full traceback on exception +-N do not emit colored output +-P run Pdb on exception + +Filename arguments +^^^^^^^^^^^^^^^^^^ * without -a and without filenames, write new and changed files. * with -a, write all files. -* with filenames, write these.""" % (__version__, argv[0]) +* with filenames, write these. + +Standard options +^^^^^^^^^^^^^^^^ +-h, --help show this help and exit +--version show version information and exit +""" % (__version__, argv[0]) def main(argv): @@ -63,9 +89,19 @@ def main(argv): nocolor() try: - opts, args = getopt.getopt(argv[1:], 'ab:t:d:c:CD:A:ng:NEqQWw:P') + opts, args = getopt.getopt(argv[1:], 'ab:t:d:c:CD:A:nNEqQWw:PThv', + ['help', 'version']) allopts = set(opt[0] for opt in opts) - srcdir = confdir = path.abspath(args[0]) + 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 + srcdir = confdir = abspath(args[0]) if not path.isdir(srcdir): print >>sys.stderr, 'Error: Cannot find source directory `%s\'.' % ( srcdir,) @@ -75,19 +111,19 @@ def main(argv): print >>sys.stderr, ('Error: Source directory doesn\'t ' 'contain conf.py file.') return 1 - outdir = path.abspath(args[1]) - if not path.isdir(outdir): - print >>sys.stderr, 'Making output directory...' - os.makedirs(outdir) - except (IndexError, getopt.error): - usage(argv) + outdir = abspath(args[1]) + except getopt.error, err: + usage(argv, 'Error: %s' % err) + return 1 + except IndexError: + usage(argv, 'Error: Insufficient arguments.') return 1 filenames = args[2:] err = 0 for filename in filenames: if not path.isfile(filename): - print >>sys.stderr, 'Cannot find file %r.' % filename + print >>sys.stderr, 'Error: Cannot find file %r.' % filename err = 1 if err: return 1 @@ -101,6 +137,8 @@ def main(argv): buildername = None force_all = freshenv = warningiserror = use_pdb = False + show_traceback = False + verbosity = 0 status = sys.stdout warning = sys.stderr error = sys.stderr @@ -113,15 +151,15 @@ def main(argv): buildername = val elif opt == '-a': if filenames: - usage(argv, 'Cannot combine -a option and filenames.') + usage(argv, 'Error: Cannot combine -a option and filenames.') return 1 force_all = True elif opt == '-t': tags.append(val) elif opt == '-d': - doctreedir = path.abspath(val) + doctreedir = abspath(val) elif opt == '-c': - confdir = path.abspath(val) + confdir = abspath(val) if not path.isfile(path.join(confdir, 'conf.py')): print >>sys.stderr, ('Error: Configuration directory ' 'doesn\'t contain conf.py file.') @@ -177,26 +215,29 @@ def main(argv): warnfile = val elif opt == '-P': use_pdb = True + elif opt == '-T': + show_traceback = True + elif opt == '-v': + verbosity += 1 + show_traceback = True if warning and warnfile: warnfp = open(warnfile, 'w') warning = Tee(warning, warnfp) error = warning + if not path.isdir(outdir): + if status: + print >>status, 'Making output directory...' + os.makedirs(outdir) + try: app = Sphinx(srcdir, confdir, outdir, doctreedir, buildername, confoverrides, status, warning, freshenv, - warningiserror, tags) + warningiserror, tags, verbosity) app.build(force_all, filenames) return app.statuscode - except KeyboardInterrupt: - if use_pdb: - import pdb - print >>error, red('Interrupted while building, starting debugger:') - traceback.print_exc() - pdb.post_mortem(sys.exc_info()[2]) - return 1 - except Exception, err: + except (Exception, KeyboardInterrupt), err: if use_pdb: import pdb print >>error, red('Exception occurred while building, ' @@ -205,7 +246,12 @@ def main(argv): pdb.post_mortem(sys.exc_info()[2]) else: print >>error - if isinstance(err, SystemMessage): + if show_traceback: + traceback.print_exc(None, error) + print >>error + if isinstance(err, KeyboardInterrupt): + print >>error, 'interrupted!' + elif isinstance(err, SystemMessage): print >>error, red('reST markup error:') print >>error, terminal_safe(err.args[0]) elif isinstance(err, SphinxError): @@ -223,7 +269,7 @@ def main(argv): 'can be provided next time.') print >>error, ( 'Either send bugs to the mailing list at ' - ',\n' + ',\n' 'or report them in the tracker at ' '. Thanks!') return 1 diff --git a/sphinx/config.py b/sphinx/config.py index 2012634e1..36a5b862a 100644 --- a/sphinx/config.py +++ b/sphinx/config.py @@ -5,7 +5,7 @@ Build configuration file handling. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ @@ -17,7 +17,7 @@ from os import path from sphinx.errors import ConfigError from sphinx.locale import l_ from sphinx.util.osutil import make_filename -from sphinx.util.pycompat import bytes, b, convert_with_2to3 +from sphinx.util.pycompat import bytes, b, execfile_ nonascii_re = re.compile(b(r'[\x80-\xff]')) @@ -110,6 +110,7 @@ class Config(object): html_secnumber_suffix = ('. ', 'html'), html_search_language = (None, 'html'), html_search_options = ({}, 'html'), + html_search_scorer = ('', None), # HTML help only options htmlhelp_basename = (lambda self: make_filename(self.project), None), @@ -141,9 +142,14 @@ class Config(object): epub_tocdup = (True, 'env'), epub_fix_images = (False, 'env'), epub_max_image_width = (0, 'env'), + epub_show_urls = ('inline', 'html'), # LaTeX options - latex_documents = ([], None), + latex_documents = (lambda self: [(self.master_doc, + make_filename(self.project) + '.tex', + self.project, + '', 'manual')], + None), latex_logo = (None, None), latex_appendices = ([], None), latex_use_parts = (False, None), @@ -166,11 +172,22 @@ class Config(object): text_newlines = ('unix', 'env'), # manpage options - man_pages = ([], None), + man_pages = (lambda self: [(self.master_doc, + make_filename(self.project).lower(), + '%s %s' % (self.project, self.release), + [], 1)], + None), man_show_urls = (False, None), # Texinfo options - texinfo_documents = ([], None), + texinfo_documents = (lambda self: [(self.master_doc, + make_filename(self.project).lower(), + self.project, '', + make_filename(self.project), + 'The %s reference manual.' % + make_filename(self.project), + 'Python')], + None), texinfo_appendices = ([], None), texinfo_elements = ({}, None), texinfo_domain_indices = (True, None), @@ -184,6 +201,9 @@ class Config(object): # gettext options gettext_compact = (True, 'gettext'), + + # XML options + xml_pretty = (True, 'env'), ) def __init__(self, dirname, filename, overrides, tags): @@ -199,26 +219,8 @@ class Config(object): # we promise to have the config dir as current dir while the # config file is executed os.chdir(dirname) - # get config source -- 'b' is a no-op under 2.x, while 'U' is - # ignored under 3.x (but 3.x compile() accepts \r\n newlines) - f = open(config_file, 'rbU') try: - source = f.read() - finally: - f.close() - try: - # compile to a code object, handle syntax errors - try: - code = compile(source, config_file, 'exec') - except SyntaxError: - if convert_with_2to3: - # maybe the file uses 2.x syntax; try to refactor to - # 3.x syntax using 2to3 - source = convert_with_2to3(config_file) - code = compile(source, config_file, 'exec') - else: - raise - exec code in config + execfile_(filename, config) except SyntaxError, err: raise ConfigError(CONFIG_SYNTAX_ERROR % err) finally: diff --git a/sphinx/directives/__init__.py b/sphinx/directives/__init__.py index 6e0300abc..388522dca 100644 --- a/sphinx/directives/__init__.py +++ b/sphinx/directives/__init__.py @@ -5,7 +5,7 @@ Handlers for additional ReST directives. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/directives/code.py b/sphinx/directives/code.py index c45e1b368..6fb21d146 100644 --- a/sphinx/directives/code.py +++ b/sphinx/directives/code.py @@ -3,7 +3,7 @@ sphinx.directives.code ~~~~~~~~~~~~~~~~~~~~~~ - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/directives/other.py b/sphinx/directives/other.py index aa4142d6f..59931a554 100644 --- a/sphinx/directives/other.py +++ b/sphinx/directives/other.py @@ -3,14 +3,13 @@ sphinx.directives.other ~~~~~~~~~~~~~~~~~~~~~~~ - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ -import os - from docutils import nodes from docutils.parsers.rst import Directive, directives +from docutils.parsers.rst.directives.admonitions import BaseAdmonition from docutils.parsers.rst.directives.misc import Class from docutils.parsers.rst.directives.misc import Include as BaseInclude @@ -19,7 +18,6 @@ from sphinx.locale import _ from sphinx.util import url_re, docname_join from sphinx.util.nodes import explicit_title_re, set_source_info, \ process_index_entry -from sphinx.util.compat import make_admonition from sphinx.util.matching import patfilter @@ -42,6 +40,7 @@ class TocTree(Directive): 'maxdepth': int, 'glob': directives.flag, 'hidden': directives.flag, + 'includehidden': directives.flag, 'numbered': int_or_nothing, 'titlesonly': directives.flag, } @@ -107,6 +106,7 @@ class TocTree(Directive): subnode['maxdepth'] = self.options.get('maxdepth', -1) subnode['glob'] = glob subnode['hidden'] = 'hidden' in self.options + subnode['includehidden'] = 'includehidden' in self.options subnode['numbered'] = self.options.get('numbered', 0) subnode['titlesonly'] = 'titlesonly' in self.options set_source_info(self, subnode) @@ -168,6 +168,7 @@ class Index(Directive): indexnode = addnodes.index() indexnode['entries'] = ne = [] indexnode['inline'] = False + set_source_info(self, indexnode) for entry in arguments: ne.extend(process_index_entry(entry, targetid)) return [indexnode, targetnode] @@ -204,29 +205,11 @@ class VersionChange(Directive): return ret -class SeeAlso(Directive): +class SeeAlso(BaseAdmonition): """ An admonition mentioning things to look at as reference. """ - has_content = True - required_arguments = 0 - optional_arguments = 1 - final_argument_whitespace = True - option_spec = {} - - def run(self): - ret = make_admonition( - addnodes.seealso, self.name, [_('See also')], self.options, - self.content, self.lineno, self.content_offset, self.block_text, - self.state, self.state_machine) - if self.arguments: - argnodes, msgs = self.state.inline_text(self.arguments[0], - self.lineno) - para = nodes.paragraph() - para += argnodes - para += msgs - ret[0].insert(1, para) - return ret + node_class = addnodes.seealso class TabularColumns(Directive): @@ -338,9 +321,46 @@ class Only(Directive): node.document = self.state.document set_source_info(self, node) node['expr'] = self.arguments[0] - self.state.nested_parse(self.content, self.content_offset, node, - match_titles=1) - return [node] + + # Same as util.nested_parse_with_titles but try to handle nested + # sections which should be raised higher up the doctree. + surrounding_title_styles = self.state.memo.title_styles + surrounding_section_level = self.state.memo.section_level + self.state.memo.title_styles = [] + self.state.memo.section_level = 0 + try: + self.state.nested_parse(self.content, self.content_offset, + node, match_titles=1) + title_styles = self.state.memo.title_styles + if (not surrounding_title_styles + or not title_styles + or title_styles[0] not in surrounding_title_styles + or not self.state.parent): + # No nested sections so no special handling needed. + return [node] + # Calculate the depths of the current and nested sections. + current_depth = 0 + parent = self.state.parent + while parent: + current_depth += 1 + parent = parent.parent + current_depth -= 2 + title_style = title_styles[0] + nested_depth = len(surrounding_title_styles) + if title_style in surrounding_title_styles: + nested_depth = surrounding_title_styles.index(title_style) + # Use these depths to determine where the nested sections should + # be placed in the doctree. + n_sects_to_raise = current_depth - nested_depth + 1 + parent = self.state.parent + for i in xrange(n_sects_to_raise): + if parent.parent: + parent = parent.parent + parent.append(node) + return [] + finally: + self.state.memo.title_styles = surrounding_title_styles + self.state.memo.section_level = surrounding_section_level class Include(BaseInclude): diff --git a/sphinx/domains/__init__.py b/sphinx/domains/__init__.py index c48568eb9..2a0e985fa 100644 --- a/sphinx/domains/__init__.py +++ b/sphinx/domains/__init__.py @@ -6,7 +6,7 @@ Support for domains, which are groupings of description directives and roles describing e.g. constructs of one programming language. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/domains/c.py b/sphinx/domains/c.py index f1848dbdb..f9f2e6647 100644 --- a/sphinx/domains/c.py +++ b/sphinx/domains/c.py @@ -5,7 +5,7 @@ The C language domain. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/domains/cpp.py b/sphinx/domains/cpp.py index a6392c1cb..9307d3a4d 100644 --- a/sphinx/domains/cpp.py +++ b/sphinx/domains/cpp.py @@ -5,7 +5,7 @@ The C++ language domain. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ @@ -672,8 +672,9 @@ class DefinitionParser(object): except ValueError: return False - def _parse_builtin(self, modifier): - path = [modifier] + def _parse_builtin(self, modifiers): + modifier = modifiers[-1] + path = modifiers following = self._modifiers[modifier] while 1: self.skip_ws() @@ -730,9 +731,10 @@ class DefinitionParser(object): # impossible for a template to follow, so what # we do is go to a different function that just # eats types - if following is not None: - return self._parse_builtin(modifier) modifiers.append(modifier) + if following is not None: + return self._parse_builtin(modifiers) + self.skip_ws() else: self.backout() break @@ -760,17 +762,33 @@ class DefinitionParser(object): self.skip_ws() if self.match(_string_re): return self.matched_text - idx1 = self.definition.find(',', self.pos) - idx2 = self.definition.find(')', self.pos) - if idx1 < 0: - idx = idx2 - elif idx2 < 0: - idx = idx1 - else: - idx = min(idx1, idx2) - if idx < 0: - self.fail('unexpected end in default expression') - rv = self.definition[self.pos:idx] + paren_stack_depth = 0 + max_pos = len(self.definition) + rv_start = self.pos + while 1: + idx0 = self.definition.find('(', self.pos) + idx1 = self.definition.find(',', self.pos) + idx2 = self.definition.find(')', self.pos) + if idx0 < 0: + idx0 = max_pos + if idx1 < 0: + idx1 = max_pos + if idx2 < 0: + idx2 = max_pos + idx = min(idx0, idx1, idx2) + if idx >= max_pos: + self.fail('unexpected end in default expression') + if idx == idx0: + paren_stack_depth += 1 + elif idx == idx2: + paren_stack_depth -= 1 + if paren_stack_depth < 0: + break + elif paren_stack_depth == 0: + break + self.pos = idx+1 + + rv = self.definition[rv_start:idx] self.pos = idx return rv @@ -836,7 +854,7 @@ class DefinitionParser(object): visibility = 'public' if self.match(_visibility_re): visibility = self.matched_text - static = self.skip_word('static') + static = self.skip_word_and_ws('static') return visibility, static def parse_type(self): diff --git a/sphinx/domains/javascript.py b/sphinx/domains/javascript.py index a6f4e87cc..862077b53 100644 --- a/sphinx/domains/javascript.py +++ b/sphinx/domains/javascript.py @@ -5,7 +5,7 @@ The JavaScript domain. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/domains/python.py b/sphinx/domains/python.py index 38f521dc4..89b7fded4 100644 --- a/sphinx/domains/python.py +++ b/sphinx/domains/python.py @@ -5,7 +5,7 @@ The Python domain. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/domains/rst.py b/sphinx/domains/rst.py index 9a40b05fa..73e7e48e9 100644 --- a/sphinx/domains/rst.py +++ b/sphinx/domains/rst.py @@ -5,7 +5,7 @@ The reStructuredText domain. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/domains/std.py b/sphinx/domains/std.py index 9148131a4..011a12bf3 100644 --- a/sphinx/domains/std.py +++ b/sphinx/domains/std.py @@ -5,7 +5,7 @@ The standard domain. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ @@ -307,12 +307,18 @@ class Glossary(Directive): # add an index entry too indexnode = addnodes.index() indexnode['entries'] = [('single', termtext, new_id, 'main')] - termnodes.append(indexnode) - termnodes.extend(res[0]) - termnodes.append(addnodes.termsep()) + _termnodes = [] + _termnodes.append(indexnode) + _termnodes.extend(res[0]) + _termnodes.append(addnodes.termsep()) + for termnode in _termnodes: + termnode.source, termnode.line = source, lineno + termnodes.extend(_termnodes) # make a single "term" node with all the terms, separated by termsep # nodes (remove the dangling trailing separator) term = nodes.term('', '', *termnodes[:-1]) + term.source, term.line = termnodes[0].source, termnodes[0].line + term.rawsource = term.astext() term['ids'].extend(ids) term['names'].extend(ids) term += system_messages diff --git a/sphinx/environment.py b/sphinx/environment.py index 5661c468a..32e8eb5bd 100644 --- a/sphinx/environment.py +++ b/sphinx/environment.py @@ -5,7 +5,7 @@ Global creation environment. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ @@ -26,30 +26,27 @@ from itertools import izip, groupby from docutils import nodes from docutils.io import FileInput, NullOutput from docutils.core import Publisher -from docutils.utils import Reporter, relative_path, new_document, \ - get_source_line +from docutils.utils import Reporter, relative_path, get_source_line from docutils.readers import standalone -from docutils.parsers.rst import roles, directives, Parser as RSTParser +from docutils.parsers.rst import roles, directives from docutils.parsers.rst.languages import en as english from docutils.parsers.rst.directives.html import MetaBody from docutils.writers import UnfilteredWriter -from docutils.transforms import Transform -from docutils.transforms.parts import ContentsFilter from sphinx import addnodes from sphinx.util import url_re, get_matching_docs, docname_join, split_into, \ FilenameUniqDict -from sphinx.util.nodes import clean_astext, make_refnode, extract_messages, \ - WarningStream -from sphinx.util.osutil import movefile, SEP, ustrftime, find_catalog +from sphinx.util.nodes import clean_astext, make_refnode, WarningStream +from sphinx.util.osutil import SEP, fs_encoding from sphinx.util.matching import compile_matchers -from sphinx.util.pycompat import all, class_types +from sphinx.util.pycompat import class_types from sphinx.util.websupport import is_commentable from sphinx.errors import SphinxError, ExtensionError -from sphinx.locale import _, init as init_locale +from sphinx.locale import _ from sphinx.versioning import add_uids, merge_doctrees +from sphinx.transforms import DefaultSubstitutions, MoveModuleTargets, \ + HandleCodeBlocks, SortIds, CitationReferences, Locale, SphinxContentsFilter -fs_encoding = sys.getfilesystemencoding() or sys.getdefaultencoding() orig_role_function = roles.role orig_directive_function = directives.directive @@ -66,19 +63,14 @@ default_settings = { 'doctitle_xform': False, 'sectsubtitle_xform': False, 'halt_level': 5, + 'file_insertion_enabled': True, } # This is increased every time an environment attribute is added # or changed to properly invalidate pickle files. -ENV_VERSION = 41 +ENV_VERSION = 42 + (sys.version_info[0] - 2) -default_substitutions = set([ - 'version', - 'release', - 'today', -]) - dummy_reporter = Reporter('', 4, 4) versioning_conditions = { @@ -93,141 +85,6 @@ class NoUri(Exception): pass -class DefaultSubstitutions(Transform): - """ - Replace some substitutions if they aren't defined in the document. - """ - # run before the default Substitutions - default_priority = 210 - - def apply(self): - config = self.document.settings.env.config - # only handle those not otherwise defined in the document - to_handle = default_substitutions - set(self.document.substitution_defs) - for ref in self.document.traverse(nodes.substitution_reference): - refname = ref['refname'] - if refname in to_handle: - text = config[refname] - if refname == 'today' and not text: - # special handling: can also specify a strftime format - text = ustrftime(config.today_fmt or _('%B %d, %Y')) - ref.replace_self(nodes.Text(text, text)) - - -class MoveModuleTargets(Transform): - """ - Move module targets that are the first thing in a section to the section - title. - - XXX Python specific - """ - default_priority = 210 - - def apply(self): - for node in self.document.traverse(nodes.target): - if not node['ids']: - continue - if (node.has_key('ismod') and - node.parent.__class__ is nodes.section and - # index 0 is the section title node - node.parent.index(node) == 1): - node.parent['ids'][0:0] = node['ids'] - node.parent.remove(node) - - -class HandleCodeBlocks(Transform): - """ - Several code block related transformations. - """ - default_priority = 210 - - def apply(self): - # move doctest blocks out of blockquotes - for node in self.document.traverse(nodes.block_quote): - if all(isinstance(child, nodes.doctest_block) for child - in node.children): - node.replace_self(node.children) - # combine successive doctest blocks - #for node in self.document.traverse(nodes.doctest_block): - # if node not in node.parent.children: - # continue - # parindex = node.parent.index(node) - # while len(node.parent) > parindex+1 and \ - # isinstance(node.parent[parindex+1], nodes.doctest_block): - # node[0] = nodes.Text(node[0] + '\n\n' + - # node.parent[parindex+1][0]) - # del node.parent[parindex+1] - - -class SortIds(Transform): - """ - Sort secion IDs so that the "id[0-9]+" one comes last. - """ - default_priority = 261 - - def apply(self): - for node in self.document.traverse(nodes.section): - if len(node['ids']) > 1 and node['ids'][0].startswith('id'): - node['ids'] = node['ids'][1:] + [node['ids'][0]] - - -class CitationReferences(Transform): - """ - Replace citation references by pending_xref nodes before the default - docutils transform tries to resolve them. - """ - default_priority = 619 - - def apply(self): - for citnode in self.document.traverse(nodes.citation_reference): - cittext = citnode.astext() - refnode = addnodes.pending_xref(cittext, reftype='citation', - reftarget=cittext, refwarn=True) - refnode.line = citnode.line or citnode.parent.line - refnode += nodes.Text('[' + cittext + ']') - citnode.parent.replace(citnode, refnode) - - -class Locale(Transform): - """ - Replace translatable nodes with their translated doctree. - """ - default_priority = 0 - def apply(self): - env = self.document.settings.env - settings, source = self.document.settings, self.document['source'] - # XXX check if this is reliable - assert source.startswith(env.srcdir) - docname = path.splitext(relative_path(env.srcdir, source))[0] - textdomain = find_catalog(docname, - self.document.settings.gettext_compact) - - # fetch translations - dirs = [path.join(env.srcdir, directory) - for directory in env.config.locale_dirs] - catalog, has_catalog = init_locale(dirs, env.config.language, - textdomain) - if not has_catalog: - return - - parser = RSTParser() - - for node, msg in extract_messages(self.document): - patch = new_document(source, settings) - msgstr = catalog.gettext(msg) - # XXX add marker to untranslated parts - if not msgstr or msgstr == msg: # as-of-yet untranslated - continue - parser.parse(msgstr, patch) - patch = patch[0] - # XXX doctest and other block markup - if not isinstance(patch, nodes.paragraph): - continue # skip for now - for child in patch.children: # update leaves - child.parent = node - node.children = patch.children - - class SphinxStandaloneReader(standalone.Reader): """ Add our own transforms. @@ -246,20 +103,6 @@ class SphinxDummyWriter(UnfilteredWriter): pass -class SphinxContentsFilter(ContentsFilter): - """ - Used with BuildEnvironment.add_toc_from() to discard cross-file links - within table-of-contents link nodes. - """ - def visit_pending_xref(self, node): - text = node.astext() - self.parent.append(nodes.literal(text, text)) - raise nodes.SkipNode - - def visit_image(self, node): - raise nodes.SkipNode - - class BuildEnvironment: """ The environment in which the ReST files are translated. @@ -289,9 +132,7 @@ class BuildEnvironment: del self.config.values domains = self.domains del self.domains - # first write to a temporary file, so that if dumping fails, - # the existing environment won't be overwritten - picklefile = open(filename + '.tmp', 'wb') + picklefile = open(filename, 'wb') # remove potentially pickling-problematic values from config for key, val in vars(self.config).items(): if key.startswith('_') or \ @@ -303,7 +144,6 @@ class BuildEnvironment: pickle.dump(self, picklefile, pickle.HIGHEST_PROTOCOL) finally: picklefile.close() - movefile(filename + '.tmp', filename) # reset attributes self.domains = domains self.config.values = values @@ -782,7 +622,11 @@ class BuildEnvironment: app.emit('doctree-read', doctree) # store time of build, for outdated files detection - self.all_docs[docname] = time.time() + # (Some filesystems have coarse timestamp resolution; + # therefore time.time() can be older than filesystem's timestamp. + # For example, FAT32 has 2sec timestamp resolution.) + self.all_docs[docname] = max( + time.time(), path.getmtime(self.doc2path(docname))) if self.versioning_condition: # get old doctree @@ -874,6 +718,7 @@ class BuildEnvironment: filterlevel = self.config.keep_warnings and 2 or 5 for node in doctree.traverse(nodes.system_message): if node['level'] < filterlevel: + self.app.debug('%s [filtered system message]', node.astext()) node.parent.remove(node) @@ -1149,8 +994,9 @@ class BuildEnvironment: anchorname=anchorname, *nodetext) para = addnodes.compact_paragraph('', '', reference) item = nodes.list_item('', para) + sub_item = build_toc(sectionnode, depth + 1) if maxdepth == 0 or depth < maxdepth: - item += build_toc(sectionnode, depth+1) + item += sub_item entries.append(item) if entries: return nodes.bullet_list('', *entries) @@ -1259,46 +1105,56 @@ class BuildEnvironment: if toctree.get('hidden', False) and not includehidden: return None - def _walk_depth(node, depth, maxdepth): + # For reading the following two helper function, it is useful to keep + # in mind the node structure of a toctree (using HTML-like node names + # for brevity): + # + # + # + # The transformation is made in two passes in order to avoid + # interactions between marking and pruning the tree (see bug #1046). + + def _toctree_prune(node, depth, maxdepth): """Utility: Cut a TOC at a specified depth.""" - - # For reading this function, it is useful to keep in mind the node - # structure of a toctree (using HTML-like node names for brevity): - # - # - for subnode in node.children[:]: if isinstance(subnode, (addnodes.compact_paragraph, nodes.list_item)): - # for

    and

  • , just indicate the depth level and - # recurse to children - subnode['classes'].append('toctree-l%d' % (depth-1)) - _walk_depth(subnode, depth, maxdepth) - + # for

    and

  • , just recurse + _toctree_prune(subnode, depth, maxdepth) elif isinstance(subnode, nodes.bullet_list): # for
      , determine if the depth is too large or if the # entry is to be collapsed if maxdepth > 0 and depth > maxdepth: subnode.parent.replace(subnode, []) else: - # to find out what to collapse, *first* walk subitems, - # since that determines which children point to the - # current page - _walk_depth(subnode, depth+1, maxdepth) # cull sub-entries whose parents aren't 'current' if (collapse and depth > 1 and 'iscurrent' not in subnode.parent): subnode.parent.remove(subnode) + else: + # recurse on visible children + _toctree_prune(subnode, depth+1, maxdepth) + def _toctree_add_classes(node, depth): + """Add 'toctree-l%d' and 'current' classes to the toctree.""" + for subnode in node.children: + if isinstance(subnode, (addnodes.compact_paragraph, + nodes.list_item)): + # for

      and

    • , indicate the depth level and recurse + subnode['classes'].append('toctree-l%d' % (depth-1)) + _toctree_add_classes(subnode, depth) + elif isinstance(subnode, nodes.bullet_list): + # for
        , just recurse + _toctree_add_classes(subnode, depth+1) elif isinstance(subnode, nodes.reference): # for , identify which entries point to the current # document and therefore may not be collapsed @@ -1321,7 +1177,7 @@ class BuildEnvironment: def _entries_from_toctree(toctreenode, parents, separate=False, subtree=False): """Return TOC entries for a toctree node.""" - refs = [(e[0], str(e[1])) for e in toctreenode['entries']] + refs = [(e[0], e[1]) for e in toctreenode['entries']] entries = [] for (title, ref) in refs: try: @@ -1408,6 +1264,8 @@ class BuildEnvironment: maxdepth = maxdepth or toctree.get('maxdepth', -1) if not titles_only and toctree.get('titlesonly', False): titles_only = True + if not includehidden and toctree.get('includehidden', False): + includehidden = True # NOTE: previously, this was separate=True, but that leads to artificial # separation when two or more toctree entries form a logical unit, so @@ -1419,8 +1277,9 @@ class BuildEnvironment: newnode = addnodes.compact_paragraph('', '', *tocentries) newnode['toctree'] = True - # prune the tree to maxdepth and replace titles, also set level classes - _walk_depth(newnode, 1, prune and maxdepth or 0) + # prune the tree to maxdepth, also set toc depth and current classes + _toctree_add_classes(newnode, 1) + _toctree_prune(newnode, 1, prune and maxdepth or 0) # set the target paths in the toctrees (they are not known at TOC # generation time) @@ -1468,8 +1327,16 @@ class BuildEnvironment: elif typ == 'citation': docname, labelid = self.citations.get(target, ('', '')) if docname: - newnode = make_refnode(builder, fromdocname, docname, - labelid, contnode) + try: + newnode = make_refnode(builder, fromdocname, + docname, labelid, contnode) + except NoUri: + # remove the ids we added in the CitationReferences + # transform since they can't be transfered to + # the contnode (if it's a Text node) + if not isinstance(contnode, nodes.Element): + del node['ids'][:] + raise # no new node found? try the missing-reference event if newnode is None: newnode = builder.app.emit_firstresult( @@ -1759,4 +1626,3 @@ class BuildEnvironment: if 'orphan' in self.metadata[docname]: continue self.warn(docname, 'document isn\'t included in any toctree') - diff --git a/sphinx/errors.py b/sphinx/errors.py index bfc2be378..aee212186 100644 --- a/sphinx/errors.py +++ b/sphinx/errors.py @@ -6,7 +6,7 @@ Contains SphinxError and a few subclasses (in an extra module to avoid circular import problems). - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/ext/__init__.py b/sphinx/ext/__init__.py index 07269dc08..fcdf6c7d6 100644 --- a/sphinx/ext/__init__.py +++ b/sphinx/ext/__init__.py @@ -5,6 +5,6 @@ Contains Sphinx features not activated by default. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/ext/autodoc.py b/sphinx/ext/autodoc.py index 6c796eec0..555a31066 100644 --- a/sphinx/ext/autodoc.py +++ b/sphinx/ext/autodoc.py @@ -7,7 +7,7 @@ the doctree, thus avoiding duplication between docstrings and documentation for those who like elaborate docstrings. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ @@ -317,26 +317,38 @@ class Documenter(object): Returns True if successful, False if an error occurred. """ + dbg = self.env.app.debug + if self.objpath: + dbg('[autodoc] from %s import %s', + self.modname, '.'.join(self.objpath)) try: + dbg('[autodoc] import %s', self.modname) __import__(self.modname) parent = None obj = self.module = sys.modules[self.modname] + dbg('[autodoc] => %r', obj) for part in self.objpath: parent = obj + dbg('[autodoc] getattr(_, %r)', part) obj = self.get_attr(obj, part) + dbg('[autodoc] => %r', obj) self.object_name = part self.parent = parent self.object = obj return True # this used to only catch SyntaxError, ImportError and AttributeError, # but importing modules with side effects can raise all kinds of errors - except Exception, err: - if self.env.app and not self.env.app.quiet: - self.env.app.info(traceback.format_exc().rstrip()) - self.directive.warn( - 'autodoc can\'t import/find %s %r, it reported error: ' - '"%s", please check your spelling and sys.path' % - (self.objtype, str(self.fullname), err)) + except Exception: + if self.objpath: + errmsg = 'autodoc: failed to import %s %r from module %r' % \ + (self.objtype, '.'.join(self.objpath), self.modname) + else: + errmsg = 'autodoc: failed to import %s %r' % \ + (self.objtype, self.fullname) + errmsg += '; the following exception was raised:\n%s' % \ + traceback.format_exc() + dbg(errmsg) + self.directive.warn(errmsg) self.env.note_reread() return False @@ -489,23 +501,29 @@ class Documenter(object): If *want_all* is True, return all members. Else, only return those members given by *self.options.members* (which may also be none). """ + analyzed_member_names = set() + if self.analyzer: + attr_docs = self.analyzer.find_attr_docs() + namespace = '.'.join(self.objpath) + for item in attr_docs.iteritems(): + if item[0][0] == namespace: + analyzed_member_names.add(item[0][1]) if not want_all: if not self.options.members: return False, [] # specific members given - ret = [] + members = [] for mname in self.options.members: try: - ret.append((mname, self.get_attr(self.object, mname))) + members.append((mname, self.get_attr(self.object, mname))) except AttributeError: - self.directive.warn('missing attribute %s in object %s' - % (mname, self.fullname)) - return False, ret - - if self.options.inherited_members: + if mname not in analyzed_member_names: + self.directive.warn('missing attribute %s in object %s' + % (mname, self.fullname)) + elif self.options.inherited_members: # safe_getmembers() uses dir() which pulls in members from all # base classes - members = safe_getmembers(self.object) + members = safe_getmembers(self.object, attr_getter=self.get_attr) else: # __dict__ contains only the members directly defined in # the class (but get them via getattr anyway, to e.g. get @@ -521,13 +539,10 @@ class Documenter(object): for mname in obj_dict.keys()] membernames = set(m[0] for m in members) # add instance attributes from the analyzer - if self.analyzer: - attr_docs = self.analyzer.find_attr_docs() - namespace = '.'.join(self.objpath) - for item in attr_docs.iteritems(): - if item[0][0] == namespace: - if item[0][1] not in membernames: - members.append((item[0][1], INSTANCEATTR)) + for aname in analyzed_member_names: + if aname not in membernames and \ + (want_all or aname in self.options.members): + members.append((aname, INSTANCEATTR)) return False, sorted(members) def filter_members(self, members, want_all): @@ -577,6 +592,7 @@ class Documenter(object): membername != '__doc__': keep = has_doc or self.options.undoc_members elif self.options.special_members and \ + self.options.special_members is not ALL and \ membername in self.options.special_members: keep = has_doc or self.options.undoc_members elif want_all and membername.startswith('_'): @@ -702,7 +718,8 @@ class Documenter(object): # parse right now, to get PycodeErrors on parsing (results will # be cached anyway) self.analyzer.find_attr_docs() - except PycodeError: + except PycodeError, err: + self.env.app.debug('[autodoc] module analyzer failed: %s', err) # no source file -- e.g. for builtin and C modules self.analyzer = None # at least add the module.__file__ as a dependency @@ -866,7 +883,7 @@ class DocstringSignatureMixin(object): """ def _find_signature(self, encoding=None): - docstrings = Documenter.get_doc(self, encoding, 2) + docstrings = Documenter.get_doc(self, encoding) if len(docstrings) != 1: return doclines = docstrings[0] @@ -881,6 +898,9 @@ class DocstringSignatureMixin(object): # the base name must match ours if not self.objpath or base != self.objpath[-1]: return + # re-prepare docstring to ignore indentation after signature + docstrings = Documenter.get_doc(self, encoding, 2) + doclines = docstrings[0] # ok, now jump over remaining empty lines and set the remaining # lines as the new doclines i = 1 @@ -992,6 +1012,18 @@ class ClassDocumenter(ModuleLevelDocumenter): def format_signature(self): if self.doc_as_attr: return '' + + # get __init__ method signature from __init__.__doc__ + if self.env.config.autodoc_docstring_signature: + # only act if the feature is enabled + init_doc = MethodDocumenter(self.directive, '__init__') + init_doc.object = self.get_attr(self.object, '__init__', None) + init_doc.objpath = ['__init__'] + result = init_doc._find_signature() + if result is not None: + # use args only for Class signature + return '(%s)' % result[0] + return ModuleLevelDocumenter.format_signature(self) def add_directive_header(self, sig): @@ -1102,7 +1134,7 @@ class MethodDocumenter(DocstringSignatureMixin, ClassLevelDocumenter): """ objtype = 'method' member_order = 50 - priority = 0 + priority = 1 # must be more than FunctionDocumenter @classmethod def can_document_member(cls, member, membername, isattr, parent): @@ -1173,7 +1205,7 @@ class AttributeDocumenter(ClassLevelDocumenter): def can_document_member(cls, member, membername, isattr, parent): isdatadesc = isdescriptor(member) and not \ isinstance(member, cls.method_types) and not \ - type(member).__name__ == "method_descriptor" + type(member).__name__ in ("type", "method_descriptor") return isdatadesc or (not isinstance(parent, ModuleDocumenter) and not inspect.isroutine(member) and not isinstance(member, class_types)) @@ -1288,6 +1320,13 @@ class AutoDirective(Directive): self.warnings = [] self.result = ViewList() + try: + source, lineno = self.reporter.get_source_and_line(self.lineno) + except AttributeError: + source = lineno = None + self.env.app.debug('[autodoc] %s:%s: input:\n%s', + source, lineno, self.block_text) + # find out what documenter to call objtype = self.name[4:] doc_class = self._registry[objtype] @@ -1308,6 +1347,8 @@ class AutoDirective(Directive): if not self.result: return self.warnings + self.env.app.debug2('[autodoc] output:\n%s', '\n'.join(self.result)) + # record all filenames as dependencies -- this will at least # partially make automatic invalidation possible for fn in self.filename_set: diff --git a/sphinx/ext/autosummary/__init__.py b/sphinx/ext/autosummary/__init__.py index 0f5c2640d..f5c5a8846 100644 --- a/sphinx/ext/autosummary/__init__.py +++ b/sphinx/ext/autosummary/__init__.py @@ -49,7 +49,7 @@ resolved to a Python object, and otherwise it becomes simple emphasis. This can be used as the default role to make links 'smart'. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/ext/autosummary/generate.py b/sphinx/ext/autosummary/generate.py index faba11605..0640a332a 100644 --- a/sphinx/ext/autosummary/generate.py +++ b/sphinx/ext/autosummary/generate.py @@ -14,7 +14,7 @@ generate: sphinx-autogen -o source/generated source/*.rst - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/ext/coverage.py b/sphinx/ext/coverage.py index 5abbee097..0e8bc4b21 100644 --- a/sphinx/ext/coverage.py +++ b/sphinx/ext/coverage.py @@ -6,7 +6,7 @@ Check Python modules and C API for coverage. Mostly written by Josip Dzolonga for the Google Highly Open Participation contest. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/ext/doctest.py b/sphinx/ext/doctest.py index 1263c4116..cd6cbf220 100644 --- a/sphinx/ext/doctest.py +++ b/sphinx/ext/doctest.py @@ -6,7 +6,7 @@ Mimic doctest by automatically executing code snippets and checking their results. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/ext/extlinks.py b/sphinx/ext/extlinks.py index 9f60cdede..aea1de177 100644 --- a/sphinx/ext/extlinks.py +++ b/sphinx/ext/extlinks.py @@ -20,7 +20,7 @@ You can also give an explicit caption, e.g. :exmpl:`Foo `. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/ext/graphviz.py b/sphinx/ext/graphviz.py index 3cb289a96..a26e34fd5 100644 --- a/sphinx/ext/graphviz.py +++ b/sphinx/ext/graphviz.py @@ -6,7 +6,7 @@ Allow graphviz-formatted graphs to be included in Sphinx-generated documents inline. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ @@ -14,7 +14,6 @@ import re import codecs import posixpath from os import path -from math import ceil from subprocess import Popen, PIPE try: from hashlib import sha1 as sha @@ -125,7 +124,7 @@ def render_dot(self, code, options, format, prefix='graphviz'): str(self.builder.config.graphviz_dot) + \ str(self.builder.config.graphviz_dot_args) ).encode('utf-8') - + fname = '%s-%s.%s' % (prefix, sha(hashkey).hexdigest(), format) if hasattr(self.builder, 'imgpath'): # HTML diff --git a/sphinx/ext/ifconfig.py b/sphinx/ext/ifconfig.py index 50c7bbefa..2e2196149 100644 --- a/sphinx/ext/ifconfig.py +++ b/sphinx/ext/ifconfig.py @@ -16,7 +16,7 @@ namespace of the project configuration (that is, all variables from ``conf.py`` are available.) - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/ext/inheritance_diagram.py b/sphinx/ext/inheritance_diagram.py index be7a6766a..6499e0782 100644 --- a/sphinx/ext/inheritance_diagram.py +++ b/sphinx/ext/inheritance_diagram.py @@ -32,7 +32,7 @@ r""" The graph is inserted as a PNG+image map into HTML and a PDF in LaTeX. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ @@ -168,7 +168,7 @@ class InheritanceGraph(object): for cls in classes: recurse(cls) - return all_classes.values() + return all_classes def class_name(self, cls, parts=0): """Given a class object, return a fully-qualified name. @@ -188,7 +188,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] + return [fullname for (_, fullname, _) in self.class_info.values()] # These are the default attrs for graphviz default_graph_attrs = { @@ -199,8 +199,8 @@ class InheritanceGraph(object): 'shape': 'box', 'fontsize': 10, 'height': 0.25, - 'fontname': 'Vera Sans, DejaVu Sans, Liberation Sans, ' - 'Arial, Helvetica, sans', + 'fontname': '"Vera Sans, DejaVu Sans, Liberation Sans, ' + 'Arial, Helvetica, sans"', 'style': '"setlinewidth(0.5)"', } default_edge_attrs = { @@ -241,12 +241,16 @@ class InheritanceGraph(object): res.append('digraph %s {\n' % name) res.append(self._format_graph_attrs(g_attrs)) - for name, fullname, bases in self.class_info: + for cls, (name, fullname, bases) in self.class_info.items(): # Write the node this_node_attrs = n_attrs.copy() - url = urls.get(fullname) - if url is not None: - this_node_attrs['URL'] = '"%s"' % url + 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: + this_node_attrs['tooltip'] = '"%s"' % doc res.append(' "%s" [%s];\n' % (name, self._format_node_attrs(this_node_attrs))) diff --git a/sphinx/ext/intersphinx.py b/sphinx/ext/intersphinx.py index 9551e3cd1..2d8b9d1f6 100644 --- a/sphinx/ext/intersphinx.py +++ b/sphinx/ext/intersphinx.py @@ -20,7 +20,7 @@ also be specified individually, e.g. if the docs should be buildable without Internet access. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ @@ -188,7 +188,17 @@ def load_mappings(app): if update: env.intersphinx_inventory = {} env.intersphinx_named_inventory = {} - for name, _, invdata in cache.itervalues(): + # Duplicate values in different inventories will shadow each + # other; which one will override which can vary between builds + # since they are specified using an unordered dict. To make + # it more consistent, we sort the named inventories and then + # add the unnamed inventories last. This means that the + # unnamed inventories will shadow the named ones but the named + # ones can still be accessed when the name is specified. + cached_vals = list(cache.itervalues()) + named_vals = sorted(v for v in cached_vals if v[0]) + unnamed_vals = [v for v in cached_vals if not v[0]] + for name, _, invdata in named_vals + unnamed_vals: if name: env.intersphinx_named_inventory[name] = invdata for type, objects in invdata.iteritems(): diff --git a/sphinx/ext/jsmath.py b/sphinx/ext/jsmath.py index bad8225bd..2b9d5d285 100644 --- a/sphinx/ext/jsmath.py +++ b/sphinx/ext/jsmath.py @@ -6,7 +6,7 @@ Set up everything for use of JSMath to display math in HTML via JavaScript. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/ext/linkcode.py b/sphinx/ext/linkcode.py new file mode 100644 index 000000000..ee7a603d1 --- /dev/null +++ b/sphinx/ext/linkcode.py @@ -0,0 +1,72 @@ +# -*- coding: utf-8 -*- +""" + sphinx.ext.linkcode + ~~~~~~~~~~~~~~~~~~~ + + Add external links to module code in Python object descriptions. + + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" + +from docutils import nodes + +from sphinx import addnodes +from sphinx.locale import _ +from sphinx.errors import SphinxError + +class LinkcodeError(SphinxError): + category = "linkcode error" + +def doctree_read(app, doctree): + env = app.builder.env + + resolve_target = getattr(env.config, 'linkcode_resolve', None) + if not callable(env.config.linkcode_resolve): + raise LinkcodeError( + "Function `linkcode_resolve` is not given in conf.py") + + domain_keys = dict( + py=['module', 'fullname'], + c=['names'], + cpp=['names'], + js=['object', 'fullname'], + ) + + for objnode in doctree.traverse(addnodes.desc): + domain = objnode.get('domain') + uris = set() + for signode in objnode: + if not isinstance(signode, addnodes.desc_signature): + continue + + # Convert signode to a specified format + info = {} + for key in domain_keys.get(domain, []): + value = signode.get(key) + if not value: + value = '' + info[key] = value + if not info: + continue + + # Call user code to resolve the link + uri = resolve_target(domain, info) + if not uri: + # no source + continue + + if uri in uris or not uri: + # only one link per name, please + continue + uris.add(uri) + + onlynode = addnodes.only(expr='html') + onlynode += nodes.reference('', '', internal=False, refuri=uri) + onlynode[0] += nodes.inline('', _('[source]'), + classes=['viewcode-link']) + signode += onlynode + +def setup(app): + app.connect('doctree-read', doctree_read) + app.add_config_value('linkcode_resolve', None, '') diff --git a/sphinx/ext/mathbase.py b/sphinx/ext/mathbase.py index 6d080b4ba..3955e4bc0 100644 --- a/sphinx/ext/mathbase.py +++ b/sphinx/ext/mathbase.py @@ -5,7 +5,7 @@ Set up math support in source files and LaTeX/text output. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/ext/mathjax.py b/sphinx/ext/mathjax.py index 7a5523643..abcbe491e 100644 --- a/sphinx/ext/mathjax.py +++ b/sphinx/ext/mathjax.py @@ -7,7 +7,7 @@ Sphinx's HTML writer -- requires the MathJax JavaScript library on your webserver/computer. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/ext/oldcmarkup.py b/sphinx/ext/oldcmarkup.py index 9dad85f45..aa10246b9 100644 --- a/sphinx/ext/oldcmarkup.py +++ b/sphinx/ext/oldcmarkup.py @@ -5,7 +5,7 @@ Extension for compatibility with old C markup (directives and roles). - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ @@ -16,7 +16,7 @@ from sphinx.util.compat import Directive _warned_oldcmarkup = False WARNING_MSG = 'using old C markup; please migrate to new-style markup ' \ '(e.g. c:function instead of cfunction), see ' \ - 'http://sphinx.pocoo.org/domains.html' + 'http://sphinx-doc.org/domains.html' class OldCDirective(Directive): diff --git a/sphinx/ext/pngmath.py b/sphinx/ext/pngmath.py index 78c331a60..3938dab17 100644 --- a/sphinx/ext/pngmath.py +++ b/sphinx/ext/pngmath.py @@ -5,7 +5,7 @@ Render math in HTML via dvipng. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ @@ -32,6 +32,13 @@ from sphinx.ext.mathbase import setup_math as mathbase_setup, wrap_displaymath class MathExtError(SphinxError): category = 'Math extension error' + def __init__(self, msg, stderr=None, stdout=None): + if stderr: + msg += '\n[stderr]\n' + stderr + if stdout: + msg += '\n[stdout]\n' + stdout + SphinxError.__init__(self, msg) + DOC_HEAD = r''' \documentclass[12pt]{article} @@ -130,8 +137,7 @@ def render_math(self, math): stdout, stderr = p.communicate() if p.returncode != 0: - raise MathExtError('latex exited with error:\n[stderr]\n%s\n' - '[stdout]\n%s' % (stderr, stdout)) + raise MathExtError('latex exited with error', stderr, stdout) ensuredir(path.dirname(outfn)) # use some standard dvipng arguments @@ -155,8 +161,7 @@ def render_math(self, math): return None, None stdout, stderr = p.communicate() if p.returncode != 0: - raise MathExtError('dvipng exited with error:\n[stderr]\n%s\n' - '[stdout]\n%s' % (stderr, stdout)) + raise MathExtError('dvipng exited with error', stderr, stdout) depth = None if use_preview: for line in stdout.splitlines(): @@ -237,7 +242,8 @@ def setup(app): app.add_config_value('pngmath_latex', 'latex', 'html') app.add_config_value('pngmath_use_preview', False, 'html') app.add_config_value('pngmath_dvipng_args', - ['-gamma 1.5', '-D 110'], 'html') + ['-gamma', '1.5', '-D', '110', '-bg', 'Transparent'], + 'html') app.add_config_value('pngmath_latex_args', [], 'html') app.add_config_value('pngmath_latex_preamble', '', 'html') app.add_config_value('pngmath_add_tooltips', True, 'html') diff --git a/sphinx/ext/refcounting.py b/sphinx/ext/refcounting.py index a8dc721d7..918e64f33 100644 --- a/sphinx/ext/refcounting.py +++ b/sphinx/ext/refcounting.py @@ -9,7 +9,7 @@ Usage: Set the `refcount_file` config value to the path to the reference count data file. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ @@ -17,6 +17,7 @@ from os import path from docutils import nodes from sphinx import addnodes +from sphinx.locale import _ # refcount annotation @@ -78,12 +79,12 @@ class Refcounts(dict): continue elif entry.result_type not in ("PyObject*", "PyVarObject*"): continue - rc = 'Return value: ' if entry.result_refs is None: - rc += "Always NULL." + rc = _('Return value: Always NULL.') + elif entry.result_refs: + rc = _('Return value: New reference.') else: - rc += (entry.result_refs and "New" or "Borrowed") + \ - " reference." + rc = _('Return value: Borrowed reference.') node.insert(0, refcount(rc, rc)) diff --git a/sphinx/ext/todo.py b/sphinx/ext/todo.py index 43f073dbf..32108b1e9 100644 --- a/sphinx/ext/todo.py +++ b/sphinx/ext/todo.py @@ -8,7 +8,7 @@ all todos of your project and lists them along with a backlink to the original location. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/ext/viewcode.py b/sphinx/ext/viewcode.py index 32840f30f..962b543bc 100644 --- a/sphinx/ext/viewcode.py +++ b/sphinx/ext/viewcode.py @@ -5,7 +5,7 @@ Add links to module code in Python object descriptions. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/highlighting.py b/sphinx/highlighting.py index 2f61c1ef1..df422321b 100644 --- a/sphinx/highlighting.py +++ b/sphinx/highlighting.py @@ -5,7 +5,7 @@ Highlight code blocks using Pygments. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ @@ -143,6 +143,12 @@ class PygmentsBridge(object): # just replace all non-ASCII characters. src = src.encode('ascii', 'replace') + if (3, 0) <= sys.version_info < (3, 2): + # Python 3.1 can't process '\r' as linesep. + # `parser.suite("print('hello')\r\n")` cause error. + if '\r\n' in src: + src = src.replace('\r\n', '\n') + if parser is None: return True @@ -207,6 +213,8 @@ class PygmentsBridge(object): if self.dest == 'html': return hlsource else: + if not isinstance(hlsource, unicode): # Py2 / Pygments < 1.6 + hlsource = hlsource.decode() return hlsource.translate(tex_hl_escape_map_new) except ErrorToken: # this is most probably not the selected language, diff --git a/sphinx/jinja2glue.py b/sphinx/jinja2glue.py index ffe3a0b3f..20d92a32d 100644 --- a/sphinx/jinja2glue.py +++ b/sphinx/jinja2glue.py @@ -5,7 +5,7 @@ Glue code for the jinja2 templating engine. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/locale/__init__.py b/sphinx/locale/__init__.py index 3aca780cf..96da67d6b 100644 --- a/sphinx/locale/__init__.py +++ b/sphinx/locale/__init__.py @@ -5,7 +5,7 @@ Locale utilities. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ @@ -159,7 +159,7 @@ admonitionlabels = { 'hint': l_('Hint'), 'important': l_('Important'), 'note': l_('Note'), - 'seealso': l_('See Also'), + 'seealso': l_('See also'), 'tip': l_('Tip'), 'warning': l_('Warning'), } diff --git a/sphinx/locale/bn/LC_MESSAGES/sphinx.mo b/sphinx/locale/bn/LC_MESSAGES/sphinx.mo index cb06ba987..b5da72d22 100644 Binary files a/sphinx/locale/bn/LC_MESSAGES/sphinx.mo and b/sphinx/locale/bn/LC_MESSAGES/sphinx.mo differ diff --git a/sphinx/locale/bn/LC_MESSAGES/sphinx.po b/sphinx/locale/bn/LC_MESSAGES/sphinx.po index 49549939d..69bd75e55 100644 --- a/sphinx/locale/bn/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/bn/LC_MESSAGES/sphinx.po @@ -639,10 +639,10 @@ msgstr "%(last_updated)s সর্বশেষ পরিবর্তন কর #: sphinx/themes/basic/layout.html:198 #, python-format msgid "" -"Created using Sphinx " +"Created using Sphinx " "%(sphinx_version)s." msgstr "" -"Sphinx %(sphinx_version)s দিয়ে " +"Sphinx %(sphinx_version)s দিয়ে " "তৈরী।" #: sphinx/themes/basic/opensearch.xml:4 diff --git a/sphinx/locale/ca/LC_MESSAGES/sphinx.mo b/sphinx/locale/ca/LC_MESSAGES/sphinx.mo index fc373e47c..bdcc3aa43 100644 Binary files a/sphinx/locale/ca/LC_MESSAGES/sphinx.mo and b/sphinx/locale/ca/LC_MESSAGES/sphinx.mo differ diff --git a/sphinx/locale/ca/LC_MESSAGES/sphinx.po b/sphinx/locale/ca/LC_MESSAGES/sphinx.po index c876228ea..c1d5a1b31 100644 --- a/sphinx/locale/ca/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/ca/LC_MESSAGES/sphinx.po @@ -633,10 +633,10 @@ msgstr "Última actualització el %(last_updated)s." #: sphinx/themes/basic/layout.html:198 #, python-format msgid "" -"Created using Sphinx " +"Created using Sphinx " "%(sphinx_version)s." msgstr "" -"Creat amb Sphinx " +"Creat amb Sphinx " "%(sphinx_version)s." #: sphinx/themes/basic/opensearch.xml:4 diff --git a/sphinx/locale/cs/LC_MESSAGES/sphinx.mo b/sphinx/locale/cs/LC_MESSAGES/sphinx.mo index ba0798db6..58037693d 100644 Binary files a/sphinx/locale/cs/LC_MESSAGES/sphinx.mo and b/sphinx/locale/cs/LC_MESSAGES/sphinx.mo differ diff --git a/sphinx/locale/cs/LC_MESSAGES/sphinx.po b/sphinx/locale/cs/LC_MESSAGES/sphinx.po index 9ed728ede..d42601bb7 100644 --- a/sphinx/locale/cs/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/cs/LC_MESSAGES/sphinx.po @@ -636,10 +636,10 @@ msgstr "Aktualizováno dne %(last_updated)s." #: sphinx/themes/basic/layout.html:198 #, python-format msgid "" -"Created using Sphinx " +"Created using Sphinx " "%(sphinx_version)s." msgstr "" -"Vytvořeno pomocí Sphinx " +"Vytvořeno pomocí Sphinx " "%(sphinx_version)s." #: sphinx/themes/basic/opensearch.xml:4 diff --git a/sphinx/locale/da/LC_MESSAGES/sphinx.mo b/sphinx/locale/da/LC_MESSAGES/sphinx.mo index d0006ee21..9c8382210 100644 Binary files a/sphinx/locale/da/LC_MESSAGES/sphinx.mo and b/sphinx/locale/da/LC_MESSAGES/sphinx.mo differ diff --git a/sphinx/locale/da/LC_MESSAGES/sphinx.po b/sphinx/locale/da/LC_MESSAGES/sphinx.po index df991aece..cf74a3890 100644 --- a/sphinx/locale/da/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/da/LC_MESSAGES/sphinx.po @@ -628,10 +628,10 @@ msgstr "Sidst opdateret %(last_updated)s." #: sphinx/themes/basic/layout.html:198 #, python-format msgid "" -"Created using Sphinx " +"Created using Sphinx " "%(sphinx_version)s." msgstr "" -"Bygget med Sphinx " +"Bygget med Sphinx " "%(sphinx_version)s." #: sphinx/themes/basic/opensearch.xml:4 diff --git a/sphinx/locale/de/LC_MESSAGES/sphinx.mo b/sphinx/locale/de/LC_MESSAGES/sphinx.mo index ce12882da..07748898a 100644 Binary files a/sphinx/locale/de/LC_MESSAGES/sphinx.mo and b/sphinx/locale/de/LC_MESSAGES/sphinx.mo differ diff --git a/sphinx/locale/de/LC_MESSAGES/sphinx.po b/sphinx/locale/de/LC_MESSAGES/sphinx.po index 50ba7490e..50db2fbaf 100644 --- a/sphinx/locale/de/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/de/LC_MESSAGES/sphinx.po @@ -629,10 +629,10 @@ msgstr "Zuletzt aktualisiert am %(last_updated)s." #: sphinx/themes/basic/layout.html:198 #, python-format msgid "" -"Created using Sphinx " +"Created using Sphinx " "%(sphinx_version)s." msgstr "" -"Mit Sphinx %(sphinx_version)s " +"Mit Sphinx %(sphinx_version)s " "erstellt." #: sphinx/themes/basic/opensearch.xml:4 diff --git a/sphinx/locale/es/LC_MESSAGES/sphinx.mo b/sphinx/locale/es/LC_MESSAGES/sphinx.mo index 87b44fe64..825cfedb8 100644 Binary files a/sphinx/locale/es/LC_MESSAGES/sphinx.mo and b/sphinx/locale/es/LC_MESSAGES/sphinx.mo differ diff --git a/sphinx/locale/es/LC_MESSAGES/sphinx.po b/sphinx/locale/es/LC_MESSAGES/sphinx.po index fbcba7d90..fda55ec73 100644 --- a/sphinx/locale/es/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/es/LC_MESSAGES/sphinx.po @@ -642,10 +642,10 @@ msgstr "Actualizado por última vez en %(last_updated)s." #: sphinx/themes/basic/layout.html:198 #, python-format msgid "" -"Created using Sphinx " +"Created using Sphinx " "%(sphinx_version)s." msgstr "" -"Creado con Sphinx " +"Creado con Sphinx " "%(sphinx_version)s." #: sphinx/themes/basic/opensearch.xml:4 diff --git a/sphinx/locale/et/LC_MESSAGES/sphinx.js b/sphinx/locale/et/LC_MESSAGES/sphinx.js index 5f51a53af..abf00ee5e 100644 --- a/sphinx/locale/et/LC_MESSAGES/sphinx.js +++ b/sphinx/locale/et/LC_MESSAGES/sphinx.js @@ -1 +1 @@ -Documentation.addTranslations({"locale": "et", "plural_expr": "(n != 1)", "messages": {"Hide Search Matches": "Varja otsingutulemused", "Permalink to this definition": "P\u00fcsilink sellele definitsioonile", "Expand sidebar": "N\u00e4ita k\u00fclgriba", "Permalink to this headline": "P\u00fcsilink sellele pealkirjale", "Collapse sidebar": "Varja k\u00fclgriba"}}); \ No newline at end of file +Documentation.addTranslations({"locale": "et", "plural_expr": "(n != 1)", "messages": {"Hide Search Matches": "Varja otsingutulemused", "Permalink to this definition": "P\u00fcsiviit sellele definitsioonile", "Expand sidebar": "N\u00e4ita k\u00fclgriba", "Permalink to this headline": "P\u00fcsiviit sellele pealkirjale", "Collapse sidebar": "Varja k\u00fclgriba"}}); \ No newline at end of file diff --git a/sphinx/locale/et/LC_MESSAGES/sphinx.mo b/sphinx/locale/et/LC_MESSAGES/sphinx.mo index 14b911c0e..176d513e1 100644 Binary files a/sphinx/locale/et/LC_MESSAGES/sphinx.mo and b/sphinx/locale/et/LC_MESSAGES/sphinx.mo differ diff --git a/sphinx/locale/et/LC_MESSAGES/sphinx.po b/sphinx/locale/et/LC_MESSAGES/sphinx.po index a687f2972..3d2e56f4f 100644 --- a/sphinx/locale/et/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/et/LC_MESSAGES/sphinx.po @@ -1,15 +1,20 @@ # Estonian translations for Sphinx. -# Copyright (C) 2010 ORGANIZATION -# This file is distributed under the same license as the Sphinx project. -# FIRST AUTHOR , 2010. +# Sphinxi eesti keele tõlge. # +# Copyright (C) 2011‒2012 Pocoo Team. +# +# This file is distributed under the same license as the Sphinx project. +# +# Aivar Annamaa , 2011 +# Ivar Smolin , 2012 + msgid "" msgstr "" -"Project-Id-Version: Sphinx 1.0pre/8b971dbc7d36\n" +"Project-Id-Version: Sphinx 1.1.3" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2011-09-21 10:06+0200\n" -"PO-Revision-Date: 2011-09-18 11:40+0200\n" -"Last-Translator: Aivar Annamaa \n" +"PO-Revision-Date: 2012-09-15 12:56+0300\n" +"Last-Translator: Ivar Smolin \n" "Language-Team: \n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" "MIME-Version: 1.0\n" @@ -18,7 +23,7 @@ msgstr "" "Generated-By: Babel 0.9.6\n" #: sphinx/config.py:81 -#, fuzzy, python-format +#, python-format msgid "%s %s documentation" msgstr "%s %s dokumentatsioon" @@ -26,22 +31,22 @@ msgstr "%s %s dokumentatsioon" #: sphinx/writers/manpage.py:67 sphinx/writers/texinfo.py:203 #, python-format msgid "%B %d, %Y" -msgstr "%B %d, %Y" +msgstr "%d. %B %Y" #: sphinx/environment.py:1625 #, python-format msgid "see %s" -msgstr "" +msgstr "vaata %s" #: sphinx/environment.py:1628 #, python-format msgid "see also %s" -msgstr "" +msgstr "vaata ka %s" #: sphinx/roles.py:175 -#, fuzzy, python-format +#, python-format msgid "Python Enhancement Proposals; PEP %s" -msgstr "Python Enhancement Proposals!PEP %s" +msgstr "Pythoni täiustusettepanekud, PEP %s" #: sphinx/builders/changes.py:73 msgid "Builtins" @@ -54,7 +59,7 @@ msgstr "Mooduli tase" #: sphinx/builders/html.py:274 #, python-format msgid "%b %d, %Y" -msgstr "%b %d, %Y" +msgstr "%d. %b %Y" #: sphinx/builders/html.py:293 sphinx/themes/basic/defindex.html:30 msgid "General Index" @@ -73,8 +78,11 @@ msgid "previous" msgstr "eelmine" #: sphinx/builders/latex.py:141 sphinx/builders/texinfo.py:196 +# paistab olevat ristviitamiseks. ei oska öelda, kas siia sobiks paremini +# 'Sektsioonis' või 'Teema' või midagi muud. sestap panin enamvähem lollikindla +# 'Pealkirjas'. (okul) msgid " (in " -msgstr " (in " +msgstr " (pealkirjas " #: sphinx/directives/other.py:136 msgid "Section author: " @@ -196,9 +204,9 @@ msgid "%s() (%s method)" msgstr "%s() (%s meetod)" #: sphinx/domains/javascript.py:109 -#, fuzzy, python-format +#, python-format msgid "%s() (class)" -msgstr "%s (C++ klass)" +msgstr "%s() (klass)" #: sphinx/domains/javascript.py:111 #, python-format @@ -216,7 +224,7 @@ msgstr "Argumendid" #: sphinx/domains/javascript.py:125 msgid "Throws" -msgstr "Throws" +msgstr "" #: sphinx/domains/javascript.py:164 sphinx/domains/python.py:560 msgid "data" @@ -232,7 +240,7 @@ msgstr "Muutujad" #: sphinx/domains/python.py:104 msgid "Raises" -msgstr "Raises" +msgstr "" #: sphinx/domains/python.py:255 sphinx/domains/python.py:312 #: sphinx/domains/python.py:324 sphinx/domains/python.py:337 @@ -278,12 +286,12 @@ msgstr "%s() (%s staatiline meetod)" #: sphinx/domains/python.py:341 #, python-format msgid "%s() (%s.%s class method)" -msgstr "%s() (%s.%s klassi meetod)" +msgstr "%s() (klassi %s.%s meetod)" #: sphinx/domains/python.py:344 #, python-format msgid "%s() (%s class method)" -msgstr "%s() (%s klassi meetod)" +msgstr "%s() (klassi %s meetod)" #: sphinx/domains/python.py:354 #, python-format @@ -305,7 +313,7 @@ msgstr "moodulid" #: sphinx/domains/python.py:537 msgid "Deprecated" -msgstr "Ebaasoovitav" +msgstr "Iganenud" #: sphinx/domains/python.py:562 sphinx/locale/__init__.py:179 msgid "exception" @@ -328,9 +336,8 @@ msgid "module" msgstr "moodul" #: sphinx/domains/python.py:695 -#, fuzzy msgid " (deprecated)" -msgstr "Ebaasoovitav" +msgstr " (iganenud)" #: sphinx/domains/rst.py:55 #, python-format @@ -362,11 +369,11 @@ msgstr "%s käsurea valik; %s" #: sphinx/domains/std.py:393 msgid "glossary term" -msgstr "termin" +msgstr "sõnastiku termin" #: sphinx/domains/std.py:394 msgid "grammar token" -msgstr "grammatika märgend" +msgstr "grammatika märk" #: sphinx/domains/std.py:395 msgid "reference label" @@ -378,7 +385,7 @@ msgstr "keskkonnamuutuja" #: sphinx/domains/std.py:397 msgid "program option" -msgstr "programmi seade" +msgstr "programmi valik" #: sphinx/domains/std.py:427 sphinx/themes/basic/genindex-single.html:32 #: sphinx/themes/basic/genindex-split.html:11 @@ -395,26 +402,26 @@ msgstr "Mooduli indeks" #: sphinx/domains/std.py:429 sphinx/themes/basic/defindex.html:25 msgid "Search Page" -msgstr "Otsingu lehekülg" +msgstr "Otsinguleht" #: sphinx/ext/autodoc.py:1002 #, python-format msgid " Bases: %s" -msgstr " Baasid: %s" +msgstr " Pärineb: %s" #: sphinx/ext/autodoc.py:1038 #, python-format msgid "alias of :class:`%s`" -msgstr "sünonüüm :class:`%s`" +msgstr "klassi :class:`%s` sünonüüm" #: sphinx/ext/todo.py:41 msgid "Todo" -msgstr "Tegemata" +msgstr "Teha" #: sphinx/ext/todo.py:109 #, python-format msgid "(The <> is located in %s, line %d.)" -msgstr "(Algne kirje asub failis %s, real %d.)" +msgstr "(<> asub failis %s real %d.)" #: sphinx/ext/todo.py:117 msgid "original entry" @@ -498,7 +505,7 @@ msgstr "Muudetud versioonis %s" #: sphinx/locale/__init__.py:170 #, python-format msgid "Deprecated since version %s" -msgstr "Ebasoovitav alates versioonist %s" +msgstr "Iganenud alates versioonist %s" #: sphinx/locale/__init__.py:176 msgid "keyword" @@ -536,7 +543,7 @@ msgstr "Otsi" #: sphinx/themes/agogo/layout.html:57 sphinx/themes/basic/searchbox.html:20 msgid "Enter search terms or a module, class or function name." -msgstr "Sisesta otsingusõna" +msgstr "Sisesta otsingusõna või mooduli/klassi/funktsiooni nimi." #: sphinx/themes/agogo/layout.html:78 sphinx/themes/basic/sourcelink.html:14 msgid "Show Source" @@ -609,17 +616,17 @@ msgstr "Info selle dokumentatsiooni kohta" #: sphinx/themes/basic/layout.html:140 msgid "Copyright" -msgstr "Copyright" +msgstr "Autoriõigused" #: sphinx/themes/basic/layout.html:189 #, python-format msgid "© Copyright %(copyright)s." -msgstr "© Copyright %(copyright)s." +msgstr "© Autoriõigused %(copyright)s." #: sphinx/themes/basic/layout.html:191 #, python-format msgid "© Copyright %(copyright)s." -msgstr "© Copyright %(copyright)s." +msgstr "© Autoriõigused %(copyright)s." #: sphinx/themes/basic/layout.html:195 #, python-format @@ -629,10 +636,10 @@ msgstr "Viimati uuendatud %(last_updated)s." #: sphinx/themes/basic/layout.html:198 #, python-format msgid "" -"Created using Sphinx " +"Created using Sphinx " "%(sphinx_version)s." msgstr "" -"Loodud Sphinx-iga (versioon: " +"Loodud Sphinxiga (versioon: " "%(sphinx_version)s)." #: sphinx/themes/basic/opensearch.xml:4 @@ -669,9 +676,9 @@ msgid "" " function will automatically search for all of the words. Pages\n" " containing fewer words won't appear in the result list." msgstr "" -"Siin saad otsida käesolevast dokumentatsioonist. Sisesta otsisõned " +"Siin saad otsida käesolevast dokumentatsioonist. Sisesta otsisõnad " "allolevasse lahtrisse ning klõpsa \"Otsi\". Tulemuseks antakse " -"leheküljed, mis sisaldavad kõiki otsisõnesid." +"leheküljed, mis sisaldavad kõiki otsisõnasid." #: sphinx/themes/basic/search.html:36 msgid "search" @@ -683,7 +690,7 @@ msgstr "Otsingutulemused" #: sphinx/themes/basic/search.html:42 msgid "Your search did not match any results." -msgstr "Otsing ei andnud tulemusi" +msgstr "Otsing ei andnud tulemusi." #: sphinx/themes/basic/searchbox.html:12 msgid "Quick search" @@ -691,13 +698,13 @@ msgstr "Kiirotsing" #: sphinx/themes/basic/sourcelink.html:11 msgid "This Page" -msgstr "Käesolev lehekülg" +msgstr "Käesolev leht" #: sphinx/themes/basic/changes/frameset.html:5 #: sphinx/themes/basic/changes/versionchanges.html:12 #, python-format msgid "Changes in Version %(version)s — %(docstitle)s" -msgstr "Muudatused versioonis %(version)s — %(docstitle)s" +msgstr "Muutused versioonis %(version)s — %(docstitle)s" #: sphinx/themes/basic/changes/rstsource.html:5 #, python-format @@ -707,28 +714,28 @@ msgstr "%(filename)s — %(docstitle)s" #: sphinx/themes/basic/changes/versionchanges.html:17 #, python-format msgid "Automatically generated list of changes in version %(version)s" -msgstr "Automaatselt genereeritud nimekiri versiooni %(version)s muudatustest" +msgstr "Automaatselt genereeritud nimekiri versiooni %(version)s muutustest" #: sphinx/themes/basic/changes/versionchanges.html:18 msgid "Library changes" -msgstr "Teegi muudatused" +msgstr "Teegi muutused" #: sphinx/themes/basic/changes/versionchanges.html:23 msgid "C API changes" -msgstr "C API muudatused" +msgstr "C API muutused" #: sphinx/themes/basic/changes/versionchanges.html:25 msgid "Other changes" -msgstr "Ülejäänud muudatused" +msgstr "Ülejäänud muutused" #: sphinx/themes/basic/static/doctools.js:154 sphinx/writers/html.py:504 #: sphinx/writers/html.py:510 msgid "Permalink to this headline" -msgstr "Püsilink sellele pealkirjale" +msgstr "Püsiviit sellele pealkirjale" #: sphinx/themes/basic/static/doctools.js:160 sphinx/writers/html.py:92 msgid "Permalink to this definition" -msgstr "Püsilink sellele definitsioonile" +msgstr "Püsiviit sellele definitsioonile" #: sphinx/themes/basic/static/doctools.js:189 msgid "Hide Search Matches" diff --git a/sphinx/locale/eu/LC_MESSAGES/sphinx.js b/sphinx/locale/eu/LC_MESSAGES/sphinx.js new file mode 100644 index 000000000..2407a0e6f --- /dev/null +++ b/sphinx/locale/eu/LC_MESSAGES/sphinx.js @@ -0,0 +1 @@ +Documentation.addTranslations({"locale": "eu", "plural_expr": "(n != 1)", "messages": {"Hide Search Matches": "Bilaketa bat-etortzeak ezkutatu", "Permalink to this definition": "Definizio honetarako esteka iraunkorra", "Expand sidebar": "Alboko barra luzatu", "Permalink to this headline": "Goiburu honetarako esteka iraunkorra", "Collapse sidebar": "Alboko barra tolestu"}}); \ No newline at end of file diff --git a/sphinx/locale/eu/LC_MESSAGES/sphinx.mo b/sphinx/locale/eu/LC_MESSAGES/sphinx.mo new file mode 100644 index 000000000..9088838f9 Binary files /dev/null and b/sphinx/locale/eu/LC_MESSAGES/sphinx.mo differ diff --git a/sphinx/locale/eu/LC_MESSAGES/sphinx.po b/sphinx/locale/eu/LC_MESSAGES/sphinx.po new file mode 100644 index 000000000..0ade62c42 --- /dev/null +++ b/sphinx/locale/eu/LC_MESSAGES/sphinx.po @@ -0,0 +1,769 @@ +# Translations template for Sphinx. +# Copyright (C) 2011 ORGANIZATION +# This file is distributed under the same license as the Sphinx project. +# Ales Zabala Alava , 2011. +# +msgid "" +msgstr "" +"Project-Id-Version: Sphinx 1.1pre/9523af9ba9aa+\n" +"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" +"POT-Creation-Date: 2011-09-21 10:06+0200\n" +"PO-Revision-Date: 2013-02-07 11:51+0100\n" +"Last-Translator: Ales Zabala Alava (Shagi) \n" +"Language-Team: Basque\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 0.9.6\n" +"Language: eu\n" + +#: sphinx/config.py:81 +#, python-format +msgid "%s %s documentation" +msgstr "%s %s dokumentazioa" + +#: sphinx/environment.py:119 sphinx/writers/latex.py:190 +#: sphinx/writers/manpage.py:67 sphinx/writers/texinfo.py:203 +#, python-format +msgid "%B %d, %Y" +msgstr "%Y %B %d" + +#: sphinx/environment.py:1625 +#, python-format +msgid "see %s" +msgstr "%s ikusi" + +#: sphinx/environment.py:1628 +#, python-format +msgid "see also %s" +msgstr "ikusi %s baita ere" + +#: sphinx/roles.py:175 +#, python-format +msgid "Python Enhancement Proposals; PEP %s" +msgstr "Python Hobekuntza Proposamena; PEP %s" + +#: sphinx/builders/changes.py:73 +msgid "Builtins" +msgstr "" + +#: sphinx/builders/changes.py:75 +msgid "Module level" +msgstr "Modulu maila" + +#: sphinx/builders/html.py:274 +#, python-format +msgid "%b %d, %Y" +msgstr "%Y %b %d" + +#: sphinx/builders/html.py:293 sphinx/themes/basic/defindex.html:30 +msgid "General Index" +msgstr "Indize orokorra" + +#: sphinx/builders/html.py:293 +msgid "index" +msgstr "indizea" + +#: sphinx/builders/html.py:353 +msgid "next" +msgstr "hurrengoa" + +#: sphinx/builders/html.py:362 +msgid "previous" +msgstr "aurrekoa" + +#: sphinx/builders/latex.py:141 sphinx/builders/texinfo.py:196 +msgid " (in " +msgstr " (hemen: " + +#: sphinx/directives/other.py:136 +msgid "Section author: " +msgstr "Atalaren egilea: " + +#: sphinx/directives/other.py:138 +msgid "Module author: " +msgstr "Moduluaren egilea: " + +#: sphinx/directives/other.py:140 +msgid "Code author: " +msgstr "Kodearen egilea: " + +#: sphinx/directives/other.py:142 +msgid "Author: " +msgstr "Egilea:" + +#: sphinx/directives/other.py:215 +msgid "See also" +msgstr "Ikusi baita ere" + +#: sphinx/domains/__init__.py:244 +#, python-format +msgid "%s %s" +msgstr "%s %s" + +#: sphinx/domains/c.py:51 sphinx/domains/python.py:95 +msgid "Parameters" +msgstr "Parametroak" + +#: sphinx/domains/c.py:54 sphinx/domains/javascript.py:128 +#: sphinx/domains/python.py:107 +msgid "Returns" +msgstr "Itzultzen du" + +#: sphinx/domains/c.py:56 sphinx/domains/python.py:109 +msgid "Return type" +msgstr "Itzulketa mota" + +#: sphinx/domains/c.py:141 +#, python-format +msgid "%s (C function)" +msgstr "%s (C funtzioa)" + +#: sphinx/domains/c.py:143 +#, python-format +msgid "%s (C member)" +msgstr "%s (C partaidea)" + +#: sphinx/domains/c.py:145 +#, python-format +msgid "%s (C macro)" +msgstr "%s (C makroa)" + +#: sphinx/domains/c.py:147 +#, python-format +msgid "%s (C type)" +msgstr "%s (C mota)" + +#: sphinx/domains/c.py:149 +#, python-format +msgid "%s (C variable)" +msgstr "%s (C aldagaia)" + +#: sphinx/domains/c.py:204 sphinx/domains/cpp.py:1060 +#: sphinx/domains/javascript.py:162 sphinx/domains/python.py:559 +msgid "function" +msgstr "funtzioa" + +#: sphinx/domains/c.py:205 sphinx/domains/cpp.py:1061 +msgid "member" +msgstr "partaidea" + +#: sphinx/domains/c.py:206 +msgid "macro" +msgstr "makroa" + +#: sphinx/domains/c.py:207 sphinx/domains/cpp.py:1062 +msgid "type" +msgstr "mota" + +#: sphinx/domains/c.py:208 +msgid "variable" +msgstr "aldagaia" + +#: sphinx/domains/cpp.py:904 +#, python-format +msgid "%s (C++ class)" +msgstr "%s (C++ klasea)" + +#: sphinx/domains/cpp.py:919 +#, python-format +msgid "%s (C++ type)" +msgstr "%s (C++ mota)" + +#: sphinx/domains/cpp.py:938 +#, python-format +msgid "%s (C++ member)" +msgstr "%s (C++ partaidea)" + +#: sphinx/domains/cpp.py:990 +#, python-format +msgid "%s (C++ function)" +msgstr "%s (C++ funtzioa)" + +#: sphinx/domains/cpp.py:1059 sphinx/domains/javascript.py:163 +#: sphinx/domains/python.py:561 +msgid "class" +msgstr "klasea" + +#: sphinx/domains/javascript.py:106 sphinx/domains/python.py:254 +#, python-format +msgid "%s() (built-in function)" +msgstr "" + +#: sphinx/domains/javascript.py:107 sphinx/domains/python.py:318 +#, python-format +msgid "%s() (%s method)" +msgstr "%s() (%s metodoa)" + +#: sphinx/domains/javascript.py:109 +#, python-format +msgid "%s() (class)" +msgstr "%s() (klasea)" + +#: sphinx/domains/javascript.py:111 +#, python-format +msgid "%s (global variable or constant)" +msgstr "%s (aldagai globala edo konstantea)" + +#: sphinx/domains/javascript.py:113 sphinx/domains/python.py:356 +#, python-format +msgid "%s (%s attribute)" +msgstr "%s (%s atributua)" + +#: sphinx/domains/javascript.py:122 +msgid "Arguments" +msgstr "Argumentuak" + +#: sphinx/domains/javascript.py:125 +msgid "Throws" +msgstr "Jaurtitzen du" + +#: sphinx/domains/javascript.py:164 sphinx/domains/python.py:560 +msgid "data" +msgstr "datuak" + +#: sphinx/domains/javascript.py:165 sphinx/domains/python.py:566 +msgid "attribute" +msgstr "atributua" + +#: sphinx/domains/python.py:100 +msgid "Variables" +msgstr "Aldagaiak" + +#: sphinx/domains/python.py:104 +msgid "Raises" +msgstr "Goratzen du" + +#: sphinx/domains/python.py:255 sphinx/domains/python.py:312 +#: sphinx/domains/python.py:324 sphinx/domains/python.py:337 +#, python-format +msgid "%s() (in module %s)" +msgstr "%s() (%s moduluan)" + +#: sphinx/domains/python.py:258 +#, python-format +msgid "%s (built-in variable)" +msgstr "" + +#: sphinx/domains/python.py:259 sphinx/domains/python.py:350 +#, python-format +msgid "%s (in module %s)" +msgstr "%s (%s moduluan)" + +#: sphinx/domains/python.py:275 +#, python-format +msgid "%s (built-in class)" +msgstr "" + +#: sphinx/domains/python.py:276 +#, python-format +msgid "%s (class in %s)" +msgstr "%s (klasea %s-(e)n)" + +#: sphinx/domains/python.py:316 +#, python-format +msgid "%s() (%s.%s method)" +msgstr "%s() (%s.%s metodoa)" + +#: sphinx/domains/python.py:328 +#, python-format +msgid "%s() (%s.%s static method)" +msgstr "%s() (%s.%s metodo estatikoa)" + +#: sphinx/domains/python.py:331 +#, python-format +msgid "%s() (%s static method)" +msgstr "%s() (%s metodo estatikoa)" + +#: sphinx/domains/python.py:341 +#, python-format +msgid "%s() (%s.%s class method)" +msgstr "%s() (%s.%s klaseko metodoa)" + +#: sphinx/domains/python.py:344 +#, python-format +msgid "%s() (%s class method)" +msgstr "%s() (%s klaseko metodoa)" + +#: sphinx/domains/python.py:354 +#, python-format +msgid "%s (%s.%s attribute)" +msgstr "%s (%s.%s atributua)" + +#: sphinx/domains/python.py:434 +#, python-format +msgid "%s (module)" +msgstr "%s (modulua)" + +#: sphinx/domains/python.py:491 +msgid "Python Module Index" +msgstr "Python moduluen indizea" + +#: sphinx/domains/python.py:492 +msgid "modules" +msgstr "moduluak" + +#: sphinx/domains/python.py:537 +msgid "Deprecated" +msgstr "Zaharkitua" + +#: sphinx/domains/python.py:562 sphinx/locale/__init__.py:179 +msgid "exception" +msgstr "salbuespena" + +#: sphinx/domains/python.py:563 +msgid "method" +msgstr "metodoa" + +#: sphinx/domains/python.py:564 +msgid "class method" +msgstr "klaseko metodoa" + +#: sphinx/domains/python.py:565 +msgid "static method" +msgstr "metodo estatikoa" + +#: sphinx/domains/python.py:567 sphinx/locale/__init__.py:175 +msgid "module" +msgstr "modulua" + +#: sphinx/domains/python.py:695 +msgid " (deprecated)" +msgstr " (zaharkitua)" + +#: sphinx/domains/rst.py:55 +#, python-format +msgid "%s (directive)" +msgstr "" + +#: sphinx/domains/rst.py:57 +#, python-format +msgid "%s (role)" +msgstr "%s (rola)" + +#: sphinx/domains/rst.py:106 +msgid "directive" +msgstr "" + +#: sphinx/domains/rst.py:107 +msgid "role" +msgstr "rola" + +#: sphinx/domains/std.py:70 sphinx/domains/std.py:86 +#, python-format +msgid "environment variable; %s" +msgstr "inguruneko aldagaia; %s" + +#: sphinx/domains/std.py:162 +#, python-format +msgid "%scommand line option; %s" +msgstr "%skomando lerroko aukera; %s" + +#: sphinx/domains/std.py:393 +msgid "glossary term" +msgstr "glosarioko terminoa" + +#: sphinx/domains/std.py:394 +msgid "grammar token" +msgstr "gramatikako token-a" + +#: sphinx/domains/std.py:395 +msgid "reference label" +msgstr "erreferentzia etiketa" + +#: sphinx/domains/std.py:396 +msgid "environment variable" +msgstr "inguruneko aldagaia" + +#: sphinx/domains/std.py:397 +msgid "program option" +msgstr "programako aukera" + +#: sphinx/domains/std.py:427 sphinx/themes/basic/genindex-single.html:32 +#: sphinx/themes/basic/genindex-split.html:11 +#: sphinx/themes/basic/genindex-split.html:14 +#: sphinx/themes/basic/genindex.html:32 sphinx/themes/basic/genindex.html:35 +#: sphinx/themes/basic/genindex.html:68 sphinx/themes/basic/layout.html:134 +#: sphinx/writers/latex.py:179 sphinx/writers/texinfo.py:456 +msgid "Index" +msgstr "Indizea" + +#: sphinx/domains/std.py:428 +msgid "Module Index" +msgstr "Moduluen indizea" + +#: sphinx/domains/std.py:429 sphinx/themes/basic/defindex.html:25 +msgid "Search Page" +msgstr "Bilaketa orria" + +#: sphinx/ext/autodoc.py:1002 +#, python-format +msgid " Bases: %s" +msgstr "" + +#: sphinx/ext/autodoc.py:1038 +#, python-format +msgid "alias of :class:`%s`" +msgstr "" + +#: sphinx/ext/todo.py:41 +msgid "Todo" +msgstr "Egitekoa" + +#: sphinx/ext/todo.py:109 +#, python-format +msgid "(The <> is located in %s, line %d.)" +msgstr "" + +#: sphinx/ext/todo.py:117 +msgid "original entry" +msgstr "jatorrizko sarrera" + +#: sphinx/ext/viewcode.py:70 +msgid "[source]" +msgstr "[iturburua]" + +#: sphinx/ext/viewcode.py:117 +msgid "[docs]" +msgstr "[dokumentazioa]" + +#: sphinx/ext/viewcode.py:131 +msgid "Module code" +msgstr "Moduluko kodea" + +#: sphinx/ext/viewcode.py:137 +#, python-format +msgid "

        Source code for %s

        " +msgstr "

        %s(r)en iturburu kodea

        " + +#: sphinx/ext/viewcode.py:164 +msgid "Overview: module code" +msgstr "Gainbegirada: moduluko kodea" + +#: sphinx/ext/viewcode.py:165 +msgid "

        All modules for which code is available

        " +msgstr "

        Kodea eskuragarri duten modulu guztiak

        " + +#: sphinx/locale/__init__.py:155 +msgid "Attention" +msgstr "Adi" + +#: sphinx/locale/__init__.py:156 +msgid "Caution" +msgstr "Kontuz" + +#: sphinx/locale/__init__.py:157 +msgid "Danger" +msgstr "Arriskua" + +#: sphinx/locale/__init__.py:158 +msgid "Error" +msgstr "Errorea" + +#: sphinx/locale/__init__.py:159 +msgid "Hint" +msgstr "Argibidea" + +#: sphinx/locale/__init__.py:160 +msgid "Important" +msgstr "Garrantzitsua" + +#: sphinx/locale/__init__.py:161 +msgid "Note" +msgstr "Nota" + +#: sphinx/locale/__init__.py:162 +msgid "See Also" +msgstr "Ikusi baita ere" + +#: sphinx/locale/__init__.py:163 +msgid "Tip" +msgstr "Iradokizuna" + +#: sphinx/locale/__init__.py:164 +msgid "Warning" +msgstr "Kontuz" + +#: sphinx/locale/__init__.py:168 +#, python-format +msgid "New in version %s" +msgstr "Berria %s bertsioan" + +#: sphinx/locale/__init__.py:169 +#, python-format +msgid "Changed in version %s" +msgstr "%s bertsioan aldatuta" + +#: sphinx/locale/__init__.py:170 +#, python-format +msgid "Deprecated since version %s" +msgstr "%s bertsiotik aurrera zaharkituta" + +#: sphinx/locale/__init__.py:176 +msgid "keyword" +msgstr "gako-hitza" + +#: sphinx/locale/__init__.py:177 +msgid "operator" +msgstr "eragiketa" + +#: sphinx/locale/__init__.py:178 +msgid "object" +msgstr "objetua" + +#: sphinx/locale/__init__.py:180 +msgid "statement" +msgstr "sententzia" + +#: sphinx/locale/__init__.py:181 +msgid "built-in function" +msgstr "" + +#: sphinx/themes/agogo/layout.html:45 sphinx/themes/basic/globaltoc.html:10 +#: sphinx/themes/basic/localtoc.html:11 +msgid "Table Of Contents" +msgstr "Eduki taula" + +#: sphinx/themes/agogo/layout.html:49 sphinx/themes/basic/layout.html:137 +#: sphinx/themes/basic/search.html:11 sphinx/themes/basic/search.html:20 +msgid "Search" +msgstr "Bilatu" + +#: sphinx/themes/agogo/layout.html:52 sphinx/themes/basic/searchbox.html:15 +msgid "Go" +msgstr "Joan" + +#: sphinx/themes/agogo/layout.html:57 sphinx/themes/basic/searchbox.html:20 +msgid "Enter search terms or a module, class or function name." +msgstr "Sartu bilaketa terminoa edo modulu, klase edo funtzioaren izena." + +#: sphinx/themes/agogo/layout.html:78 sphinx/themes/basic/sourcelink.html:14 +msgid "Show Source" +msgstr "Iturburua ikusi" + +#: sphinx/themes/basic/defindex.html:11 +msgid "Overview" +msgstr "Gainbegirada" + +#: sphinx/themes/basic/defindex.html:20 +msgid "Indices and tables:" +msgstr "Indizeak eta taulak:" + +#: sphinx/themes/basic/defindex.html:23 +msgid "Complete Table of Contents" +msgstr "Eduki taula osoa" + +#: sphinx/themes/basic/defindex.html:24 +msgid "lists all sections and subsections" +msgstr "atal eta azpiatal guztiak zerrendatu" + +#: sphinx/themes/basic/defindex.html:26 +msgid "search this documentation" +msgstr "dokumentazio honetan bilatu" + +#: sphinx/themes/basic/defindex.html:28 +msgid "Global Module Index" +msgstr "Modulu indize globala" + +#: sphinx/themes/basic/defindex.html:29 +msgid "quick access to all modules" +msgstr "modulu guztietara atzipen azkarra" + +#: sphinx/themes/basic/defindex.html:31 +msgid "all functions, classes, terms" +msgstr "funtzio, klase, termino guztiak" + +#: sphinx/themes/basic/genindex-single.html:35 +#, python-format +msgid "Index – %(key)s" +msgstr "Indizea – %(key)s" + +#: sphinx/themes/basic/genindex-single.html:63 +#: sphinx/themes/basic/genindex-split.html:24 +#: sphinx/themes/basic/genindex-split.html:38 +#: sphinx/themes/basic/genindex.html:74 +msgid "Full index on one page" +msgstr "Indize guztia orri batean" + +#: sphinx/themes/basic/genindex-split.html:16 +msgid "Index pages by letter" +msgstr "Indize orriak hizkika" + +#: sphinx/themes/basic/genindex-split.html:25 +msgid "can be huge" +msgstr "handia izan daiteke" + +#: sphinx/themes/basic/layout.html:29 +msgid "Navigation" +msgstr "Nabigazioa" + +#: sphinx/themes/basic/layout.html:122 +#, python-format +msgid "Search within %(docstitle)s" +msgstr "Bilatu %(docstitle)s(e)n" + +#: sphinx/themes/basic/layout.html:131 +msgid "About these documents" +msgstr "Dokumentu hauen inguruan" + +#: sphinx/themes/basic/layout.html:140 +msgid "Copyright" +msgstr "Copyright" + +#: sphinx/themes/basic/layout.html:189 +#, python-format +msgid "© Copyright %(copyright)s." +msgstr "© Copyright %(copyright)s." + +#: sphinx/themes/basic/layout.html:191 +#, python-format +msgid "© Copyright %(copyright)s." +msgstr "© Copyright %(copyright)s." + +#: sphinx/themes/basic/layout.html:195 +#, python-format +msgid "Last updated on %(last_updated)s." +msgstr "Azken aldaketa: %(last_updated)s." + +#: sphinx/themes/basic/layout.html:198 +#, python-format +msgid "" +"Created using Sphinx " +"%(sphinx_version)s." +msgstr "" +"Sphinx %(sphinx_version)s erabiliz " +"sortutakoa." + +#: sphinx/themes/basic/opensearch.xml:4 +#, python-format +msgid "Search %(docstitle)s" +msgstr "%(docstitle)s bilatu" + +#: sphinx/themes/basic/relations.html:11 +msgid "Previous topic" +msgstr "Aurreko gaia" + +#: sphinx/themes/basic/relations.html:13 +msgid "previous chapter" +msgstr "aurreko kapitulua" + +#: sphinx/themes/basic/relations.html:16 +msgid "Next topic" +msgstr "Hurrengo gaia" + +#: sphinx/themes/basic/relations.html:18 +msgid "next chapter" +msgstr "hurrengo kapitulua" + +#: sphinx/themes/basic/search.html:24 +msgid "" +"Please activate JavaScript to enable the search\n" +" functionality." +msgstr "Mesedez, gaitu JavaScript-a bilaketa erabili ahal izateko." + +#: sphinx/themes/basic/search.html:29 +msgid "" +"From here you can search these documents. Enter your search\n" +" words into the box below and click \"search\". Note that the search\n" +" function will automatically search for all of the words. Pages\n" +" containing fewer words won't appear in the result list." +msgstr "" +"Honekin dokumentu hauetan bilatu dezakezu. Sartu zure bilaketa hitzak\n" +"ondoko kutxan eta \"bilatu\" sakatu. Kontutan eduki bilaketa funtzioak\n" +"hitz guztiak bilatuko dituela. Hitz gutxiago dituzten orriak ez dira \n" +"emaitzen zerrendan agertuko." + +#: sphinx/themes/basic/search.html:36 +msgid "search" +msgstr "bilatu" + +#: sphinx/themes/basic/search.html:40 +msgid "Search Results" +msgstr "Bilaketa emaitzak" + +#: sphinx/themes/basic/search.html:42 +msgid "Your search did not match any results." +msgstr "Zure bilaketak ez du emaitzarik eman." + +#: sphinx/themes/basic/searchbox.html:12 +msgid "Quick search" +msgstr "Bilaketa azkarra" + +#: sphinx/themes/basic/sourcelink.html:11 +msgid "This Page" +msgstr "Orri hau" + +#: sphinx/themes/basic/changes/frameset.html:5 +#: sphinx/themes/basic/changes/versionchanges.html:12 +#, python-format +msgid "Changes in Version %(version)s — %(docstitle)s" +msgstr "%(version)s bertsioko aldaketak — %(docstitle)s" + +#: sphinx/themes/basic/changes/rstsource.html:5 +#, python-format +msgid "%(filename)s — %(docstitle)s" +msgstr "%(filename)s — %(docstitle)s" + +#: sphinx/themes/basic/changes/versionchanges.html:17 +#, python-format +msgid "Automatically generated list of changes in version %(version)s" +msgstr "Automatikoki sortutako %(version)s bertsioaren aldaketen zerrenda" + +#: sphinx/themes/basic/changes/versionchanges.html:18 +msgid "Library changes" +msgstr "Liburutegi aldaketak" + +#: sphinx/themes/basic/changes/versionchanges.html:23 +msgid "C API changes" +msgstr "C API aldaketak" + +#: sphinx/themes/basic/changes/versionchanges.html:25 +msgid "Other changes" +msgstr "Beste aldaketak" + +#: sphinx/themes/basic/static/doctools.js:154 sphinx/writers/html.py:504 +#: sphinx/writers/html.py:510 +msgid "Permalink to this headline" +msgstr "Goiburu honetarako esteka iraunkorra" + +#: sphinx/themes/basic/static/doctools.js:160 sphinx/writers/html.py:92 +msgid "Permalink to this definition" +msgstr "Definizio honetarako esteka iraunkorra" + +#: sphinx/themes/basic/static/doctools.js:189 +msgid "Hide Search Matches" +msgstr "Bilaketa bat-etortzeak ezkutatu" + +#: sphinx/themes/default/static/sidebar.js:69 +msgid "Expand sidebar" +msgstr "Alboko barra luzatu" + +#: sphinx/themes/default/static/sidebar.js:82 +#: sphinx/themes/default/static/sidebar.js:110 +msgid "Collapse sidebar" +msgstr "Alboko barra tolestu" + +#: sphinx/themes/haiku/layout.html:26 +msgid "Contents" +msgstr "Edukiak" + +#: sphinx/writers/latex.py:177 +msgid "Release" +msgstr "Argitalpena" + +#: sphinx/writers/latex.py:594 sphinx/writers/manpage.py:182 +#: sphinx/writers/texinfo.py:589 +msgid "Footnotes" +msgstr "Oin-oharrak" + +#: sphinx/writers/latex.py:676 +msgid "continued from previous page" +msgstr "aurreko orritik jarraitzen du" + +#: sphinx/writers/latex.py:681 +msgid "Continued on next page" +msgstr "Hurrengo orrian jarraitzen du" + +#: sphinx/writers/text.py:437 +msgid "[image]" +msgstr "[irudia]" diff --git a/sphinx/locale/fa/LC_MESSAGES/sphinx.mo b/sphinx/locale/fa/LC_MESSAGES/sphinx.mo index fe705e767..a4900c710 100644 Binary files a/sphinx/locale/fa/LC_MESSAGES/sphinx.mo and b/sphinx/locale/fa/LC_MESSAGES/sphinx.mo differ diff --git a/sphinx/locale/fa/LC_MESSAGES/sphinx.po b/sphinx/locale/fa/LC_MESSAGES/sphinx.po index 92caf31a0..5a149d1c0 100644 --- a/sphinx/locale/fa/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/fa/LC_MESSAGES/sphinx.po @@ -635,10 +635,10 @@ msgstr ". %(last_updated)s آخرین بروز رسانی در" #: sphinx/themes/basic/layout.html:198 #, python-format msgid "" -"Created using Sphinx " +"Created using Sphinx " "%(sphinx_version)s." msgstr "" -". Sphinx %(sphinx_version)s " +". Sphinx %(sphinx_version)s " "ایجاد شده با" #: sphinx/themes/basic/opensearch.xml:4 diff --git a/sphinx/locale/fi/LC_MESSAGES/sphinx.mo b/sphinx/locale/fi/LC_MESSAGES/sphinx.mo index 497088c8f..992d6dc2b 100644 Binary files a/sphinx/locale/fi/LC_MESSAGES/sphinx.mo and b/sphinx/locale/fi/LC_MESSAGES/sphinx.mo differ diff --git a/sphinx/locale/fi/LC_MESSAGES/sphinx.po b/sphinx/locale/fi/LC_MESSAGES/sphinx.po index 4a329546d..a59dbade1 100644 --- a/sphinx/locale/fi/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/fi/LC_MESSAGES/sphinx.po @@ -632,7 +632,7 @@ msgstr "" #: sphinx/themes/basic/layout.html:198 #, python-format msgid "" -"Created using Sphinx " +"Created using Sphinx " "%(sphinx_version)s." msgstr "" diff --git a/sphinx/locale/fr/LC_MESSAGES/sphinx.mo b/sphinx/locale/fr/LC_MESSAGES/sphinx.mo index 1027a790e..bc9717033 100644 Binary files a/sphinx/locale/fr/LC_MESSAGES/sphinx.mo and b/sphinx/locale/fr/LC_MESSAGES/sphinx.mo differ diff --git a/sphinx/locale/fr/LC_MESSAGES/sphinx.po b/sphinx/locale/fr/LC_MESSAGES/sphinx.po index 7f51effd1..3bae76325 100644 --- a/sphinx/locale/fr/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/fr/LC_MESSAGES/sphinx.po @@ -635,10 +635,10 @@ msgstr "Mis à jour le %(last_updated)s." #: sphinx/themes/basic/layout.html:198 #, python-format msgid "" -"Created using Sphinx " +"Created using Sphinx " "%(sphinx_version)s." msgstr "" -"Créé avec Sphinx " +"Créé avec Sphinx " "%(sphinx_version)s." #: sphinx/themes/basic/opensearch.xml:4 diff --git a/sphinx/locale/hr/LC_MESSAGES/sphinx.mo b/sphinx/locale/hr/LC_MESSAGES/sphinx.mo index a9bdb145c..31dbb290f 100644 Binary files a/sphinx/locale/hr/LC_MESSAGES/sphinx.mo and b/sphinx/locale/hr/LC_MESSAGES/sphinx.mo differ diff --git a/sphinx/locale/hr/LC_MESSAGES/sphinx.po b/sphinx/locale/hr/LC_MESSAGES/sphinx.po index 15e70346b..e063212d8 100644 --- a/sphinx/locale/hr/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/hr/LC_MESSAGES/sphinx.po @@ -630,10 +630,10 @@ msgstr "Zadnji put ažurirano %(last_updated)s." #: sphinx/themes/basic/layout.html:198 #, python-format msgid "" -"Created using Sphinx " +"Created using Sphinx " "%(sphinx_version)s." msgstr "" -"Izrađeno sa Sphinx " +"Izrađeno sa Sphinx " "%(sphinx_version)s." #: sphinx/themes/basic/opensearch.xml:4 diff --git a/sphinx/locale/hu/LC_MESSAGES/sphinx.js b/sphinx/locale/hu/LC_MESSAGES/sphinx.js index 2d347242b..856311d19 100644 --- a/sphinx/locale/hu/LC_MESSAGES/sphinx.js +++ b/sphinx/locale/hu/LC_MESSAGES/sphinx.js @@ -1 +1 @@ -Documentation.addTranslations({"locale": "hu", "plural_expr": "(n != 1)", "messages": {"Hide Search Matches": "Keresési találatok elrejtése", "Permalink to this definition": "Hivatkozás erre a definícióra", "Expand sidebar": "Oldalsáv kinyitása", "Permalink to this headline": "Hivatkozás erre a fejezetcímre", "Collapse sidebar": "Oldalsáv összezárása"}}); \ No newline at end of file +Documentation.addTranslations({"locale": "hu", "plural_expr": "0", "messages": {"Hide Search Matches": "Keres\u00e9si Tal\u00e1latok Elrejt\u00e9se", "Permalink to this definition": "Hivatkoz\u00e1s erre a defin\u00edci\u00f3ra", "Expand sidebar": "Oldals\u00e1v kinyit\u00e1sa", "Permalink to this headline": "Hivatkoz\u00e1s erre a fejezetc\u00edmre", "Collapse sidebar": "Oldals\u00e1v \u00f6sszez\u00e1r\u00e1sa"}}); \ No newline at end of file diff --git a/sphinx/locale/hu/LC_MESSAGES/sphinx.mo b/sphinx/locale/hu/LC_MESSAGES/sphinx.mo index 63c64bcb6..8e3614a3f 100644 Binary files a/sphinx/locale/hu/LC_MESSAGES/sphinx.mo and b/sphinx/locale/hu/LC_MESSAGES/sphinx.mo differ diff --git a/sphinx/locale/hu/LC_MESSAGES/sphinx.po b/sphinx/locale/hu/LC_MESSAGES/sphinx.po index 8f01bdced..1a51d3bfc 100644 --- a/sphinx/locale/hu/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/hu/LC_MESSAGES/sphinx.po @@ -438,10 +438,10 @@ msgstr "Utolsó frissítés %(last_updated)s." #: sphinx/themes/basic/layout.html:198 #, python-format msgid "" -"Created using Sphinx " +"Created using Sphinx " "%(sphinx_version)s." msgstr "" -"Sphinx " +"Sphinx " "%(sphinx_version)s használatával készült." #: sphinx/themes/basic/opensearch.xml:4 diff --git a/sphinx/locale/it/LC_MESSAGES/sphinx.mo b/sphinx/locale/it/LC_MESSAGES/sphinx.mo index a4213c8e0..04dfdec21 100644 Binary files a/sphinx/locale/it/LC_MESSAGES/sphinx.mo and b/sphinx/locale/it/LC_MESSAGES/sphinx.mo differ diff --git a/sphinx/locale/it/LC_MESSAGES/sphinx.po b/sphinx/locale/it/LC_MESSAGES/sphinx.po index ccfab24e2..1877c786d 100644 --- a/sphinx/locale/it/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/it/LC_MESSAGES/sphinx.po @@ -633,10 +633,10 @@ msgstr "Ultimo aggiornamento %(last_updated)s." #: sphinx/themes/basic/layout.html:198 #, python-format msgid "" -"Created using Sphinx " +"Created using Sphinx " "%(sphinx_version)s." msgstr "" -"Creato con Sphinx " +"Creato con Sphinx " "%(sphinx_version)s." #: sphinx/themes/basic/opensearch.xml:4 diff --git a/sphinx/locale/ja/LC_MESSAGES/sphinx.mo b/sphinx/locale/ja/LC_MESSAGES/sphinx.mo index c2bf5ac21..aadbb4010 100644 Binary files a/sphinx/locale/ja/LC_MESSAGES/sphinx.mo and b/sphinx/locale/ja/LC_MESSAGES/sphinx.mo differ diff --git a/sphinx/locale/ja/LC_MESSAGES/sphinx.po b/sphinx/locale/ja/LC_MESSAGES/sphinx.po index 1e3b1e760..a0b473ff8 100644 --- a/sphinx/locale/ja/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/ja/LC_MESSAGES/sphinx.po @@ -630,10 +630,10 @@ msgstr "最終更新: %(last_updated)s" #: sphinx/themes/basic/layout.html:198 #, python-format msgid "" -"Created using Sphinx " +"Created using Sphinx " "%(sphinx_version)s." msgstr "" -"このドキュメントは Sphinx " +"このドキュメントは Sphinx " "%(sphinx_version)s で生成しました。" #: sphinx/themes/basic/opensearch.xml:4 diff --git a/sphinx/locale/ko/LC_MESSAGES/sphinx.po b/sphinx/locale/ko/LC_MESSAGES/sphinx.po index 8c0dd3d83..5bee2ab75 100644 --- a/sphinx/locale/ko/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/ko/LC_MESSAGES/sphinx.po @@ -635,10 +635,10 @@ msgstr "최종 업데이트: %(last_updated)s" #: sphinx/themes/basic/layout.html:198 #, fuzzy, python-format msgid "" -"Created using Sphinx " +"Created using Sphinx " "%(sphinx_version)s." msgstr "" -"이 문서는 Sphinx%(sphinx_version)s로 " +"이 문서는 Sphinx%(sphinx_version)s로 " "제공됩니다." #: sphinx/themes/basic/opensearch.xml:4 diff --git a/sphinx/locale/lt/LC_MESSAGES/sphinx.mo b/sphinx/locale/lt/LC_MESSAGES/sphinx.mo index 9efc6d773..d9444da49 100644 Binary files a/sphinx/locale/lt/LC_MESSAGES/sphinx.mo and b/sphinx/locale/lt/LC_MESSAGES/sphinx.mo differ diff --git a/sphinx/locale/lt/LC_MESSAGES/sphinx.po b/sphinx/locale/lt/LC_MESSAGES/sphinx.po index b331d52ae..fdffdcad3 100644 --- a/sphinx/locale/lt/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/lt/LC_MESSAGES/sphinx.po @@ -628,10 +628,10 @@ msgstr "Paskutinis atnaujinimas %(last_updated)s." #: sphinx/themes/basic/layout.html:198 #, python-format msgid "" -"Created using Sphinx " +"Created using Sphinx " "%(sphinx_version)s." msgstr "" -"Sukurta naudojant Sphinx " +"Sukurta naudojant Sphinx " "%(sphinx_version)s." #: sphinx/themes/basic/opensearch.xml:4 diff --git a/sphinx/locale/lv/LC_MESSAGES/sphinx.mo b/sphinx/locale/lv/LC_MESSAGES/sphinx.mo index e6e713a5a..c173f6f5d 100644 Binary files a/sphinx/locale/lv/LC_MESSAGES/sphinx.mo and b/sphinx/locale/lv/LC_MESSAGES/sphinx.mo differ diff --git a/sphinx/locale/lv/LC_MESSAGES/sphinx.po b/sphinx/locale/lv/LC_MESSAGES/sphinx.po index ec19bbeec..381aa4b56 100644 --- a/sphinx/locale/lv/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/lv/LC_MESSAGES/sphinx.po @@ -628,10 +628,10 @@ msgstr "Pēdējas izmaiņas %(last_updated)s." #: sphinx/themes/basic/layout.html:198 #, python-format msgid "" -"Created using Sphinx " +"Created using Sphinx " "%(sphinx_version)s." msgstr "" -"Sagatavots izmantojot Sphinx " +"Sagatavots izmantojot Sphinx " "%(sphinx_version)s." #: sphinx/themes/basic/opensearch.xml:4 diff --git a/sphinx/locale/nb_NO/LC_MESSAGES/sphinx.js b/sphinx/locale/nb_NO/LC_MESSAGES/sphinx.js new file mode 100644 index 000000000..9f3099224 --- /dev/null +++ b/sphinx/locale/nb_NO/LC_MESSAGES/sphinx.js @@ -0,0 +1 @@ +Documentation.addTranslations({"locale": "nb_NO", "plural_expr": "(n != 1)", "messages": {"Hide Search Matches": "Skjul s\u00f8keresultat", "Permalink to this definition": "Permalink til denne definisjonen", "Expand sidebar": "Utvid sidepanelet", "Permalink to this headline": "Permalink til denne oversikten", "Collapse sidebar": "Skjul sidepanelet"}}); \ No newline at end of file diff --git a/sphinx/locale/nb_NO/LC_MESSAGES/sphinx.mo b/sphinx/locale/nb_NO/LC_MESSAGES/sphinx.mo new file mode 100644 index 000000000..88a534395 Binary files /dev/null and b/sphinx/locale/nb_NO/LC_MESSAGES/sphinx.mo differ diff --git a/sphinx/locale/no_NB/LC_MESSAGES/sphinx.po b/sphinx/locale/nb_NO/LC_MESSAGES/sphinx.po similarity index 99% rename from sphinx/locale/no_NB/LC_MESSAGES/sphinx.po rename to sphinx/locale/nb_NO/LC_MESSAGES/sphinx.po index 2c7dd857a..05893a881 100644 --- a/sphinx/locale/no_NB/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/nb_NO/LC_MESSAGES/sphinx.po @@ -624,10 +624,10 @@ msgstr "Sist oppdatert %(last_updated)s." #: sphinx/themes/basic/layout.html:198 #, python-format msgid "" -"Created using Sphinx " +"Created using Sphinx " "%(sphinx_version)s." msgstr "" -"Lagd med Sphinx " +"Lagd med Sphinx " "%(sphinx_version)s." #: sphinx/themes/basic/opensearch.xml:4 diff --git a/sphinx/locale/ne/LC_MESSAGES/sphinx.mo b/sphinx/locale/ne/LC_MESSAGES/sphinx.mo index 05be753d1..0e3576638 100644 Binary files a/sphinx/locale/ne/LC_MESSAGES/sphinx.mo and b/sphinx/locale/ne/LC_MESSAGES/sphinx.mo differ diff --git a/sphinx/locale/ne/LC_MESSAGES/sphinx.po b/sphinx/locale/ne/LC_MESSAGES/sphinx.po index 9dc24c83a..3ded0ab09 100644 --- a/sphinx/locale/ne/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/ne/LC_MESSAGES/sphinx.po @@ -628,7 +628,7 @@ msgstr "यो भन्दा अगाडी %(last_updated)s मा अपड #: sphinx/themes/basic/layout.html:198 #, python-format msgid "" -"Created using Sphinx " +"Created using Sphinx " "%(sphinx_version)s." msgstr "" diff --git a/sphinx/locale/nl/LC_MESSAGES/sphinx.mo b/sphinx/locale/nl/LC_MESSAGES/sphinx.mo index 05ee5662b..4b43d500a 100644 Binary files a/sphinx/locale/nl/LC_MESSAGES/sphinx.mo and b/sphinx/locale/nl/LC_MESSAGES/sphinx.mo differ diff --git a/sphinx/locale/nl/LC_MESSAGES/sphinx.po b/sphinx/locale/nl/LC_MESSAGES/sphinx.po index 473baadc8..77de479de 100644 --- a/sphinx/locale/nl/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/nl/LC_MESSAGES/sphinx.po @@ -632,10 +632,10 @@ msgstr "Laatste aanpassing op %(last_updated)s." #: sphinx/themes/basic/layout.html:198 #, python-format msgid "" -"Created using Sphinx " +"Created using Sphinx " "%(sphinx_version)s." msgstr "" -"Aangemaakt met Sphinx " +"Aangemaakt met Sphinx " "%(sphinx_version)s." #: sphinx/themes/basic/opensearch.xml:4 diff --git a/sphinx/locale/no_NB/LC_MESSAGES/sphinx.js b/sphinx/locale/no_NB/LC_MESSAGES/sphinx.js deleted file mode 100644 index d00991b2a..000000000 --- a/sphinx/locale/no_NB/LC_MESSAGES/sphinx.js +++ /dev/null @@ -1 +0,0 @@ -Documentation.addTranslations({"locale": "no_NB", "plural_expr": "(n != 1)", "messages": {"Hide Search Matches": "Skjul S\u00f6kresultater", "Permalink to this definition": "Permalink til denne definisjonen", "Expand sidebar": "Utvid sidepanelet", "Permalink to this headline": "Permalink til denne overskriften", "Collapse sidebar": "Kollaps sidepanelet"}}); \ No newline at end of file diff --git a/sphinx/locale/no_NB/LC_MESSAGES/sphinx.mo b/sphinx/locale/no_NB/LC_MESSAGES/sphinx.mo deleted file mode 100644 index eba1f773f..000000000 Binary files a/sphinx/locale/no_NB/LC_MESSAGES/sphinx.mo and /dev/null differ diff --git a/sphinx/locale/pl/LC_MESSAGES/sphinx.mo b/sphinx/locale/pl/LC_MESSAGES/sphinx.mo index bdceda436..c6c8a0b0e 100644 Binary files a/sphinx/locale/pl/LC_MESSAGES/sphinx.mo and b/sphinx/locale/pl/LC_MESSAGES/sphinx.mo differ diff --git a/sphinx/locale/pl/LC_MESSAGES/sphinx.po b/sphinx/locale/pl/LC_MESSAGES/sphinx.po index 957d23e91..f6379d340 100644 --- a/sphinx/locale/pl/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/pl/LC_MESSAGES/sphinx.po @@ -556,7 +556,7 @@ msgstr "wszystkie rozdziały i podrozdziały" #: sphinx/themes/basic/defindex.html:26 msgid "search this documentation" -msgstr "przyszukaj tę dokumentację" +msgstr "przeszukaj tę dokumentację" #: sphinx/themes/basic/defindex.html:28 msgid "Global Module Index" @@ -625,10 +625,10 @@ msgstr "Ostatnia modyfikacja %(last_updated)s." #: sphinx/themes/basic/layout.html:198 #, python-format msgid "" -"Created using Sphinx " +"Created using Sphinx " "%(sphinx_version)s." msgstr "" -"Utworzone przy pomocy Sphinx'a " +"Utworzone przy pomocy Sphinx'a " "%(sphinx_version)s." #: sphinx/themes/basic/opensearch.xml:4 @@ -656,7 +656,7 @@ msgstr "następny rozdział" msgid "" "Please activate JavaScript to enable the search\n" " functionality." -msgstr "Aby umożliwić wuszukiwanie, proszę włączyć JavaScript." +msgstr "Aby umożliwić wyszukiwanie, proszę włączyć JavaScript." #: sphinx/themes/basic/search.html:29 msgid "" @@ -696,7 +696,7 @@ msgstr "Ta strona" #: sphinx/themes/basic/changes/versionchanges.html:12 #, python-format msgid "Changes in Version %(version)s — %(docstitle)s" -msgstr "Zmiany w wesji %(version)s — %(docstitle)s" +msgstr "Zmiany w wersji %(version)s — %(docstitle)s" #: sphinx/themes/basic/changes/rstsource.html:5 #, python-format diff --git a/sphinx/locale/pt_BR/LC_MESSAGES/sphinx.mo b/sphinx/locale/pt_BR/LC_MESSAGES/sphinx.mo index 3016d5ef7..824ba0482 100644 Binary files a/sphinx/locale/pt_BR/LC_MESSAGES/sphinx.mo and b/sphinx/locale/pt_BR/LC_MESSAGES/sphinx.mo differ diff --git a/sphinx/locale/pt_BR/LC_MESSAGES/sphinx.po b/sphinx/locale/pt_BR/LC_MESSAGES/sphinx.po index b41b5ad18..bb4837662 100644 --- a/sphinx/locale/pt_BR/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/pt_BR/LC_MESSAGES/sphinx.po @@ -628,10 +628,10 @@ msgstr "Última atualização em %(last_updated)s." #: sphinx/themes/basic/layout.html:198 #, python-format msgid "" -"Created using Sphinx " +"Created using Sphinx " "%(sphinx_version)s." msgstr "" -"Criado com Sphinx " +"Criado com Sphinx " "%(sphinx_version)s." #: sphinx/themes/basic/opensearch.xml:4 diff --git a/sphinx/locale/ru/LC_MESSAGES/sphinx.js b/sphinx/locale/ru/LC_MESSAGES/sphinx.js index ca0376ac6..294b82f96 100644 --- a/sphinx/locale/ru/LC_MESSAGES/sphinx.js +++ b/sphinx/locale/ru/LC_MESSAGES/sphinx.js @@ -1 +1 @@ -Documentation.addTranslations({"locale": "ru", "plural_expr": "n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2", "messages": {"Hide Search Matches": "\u0421\u043d\u044f\u0442\u044c \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u0438\u0435", "Permalink to this definition": "\u0421\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u044d\u0442\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435", "Expand sidebar": "", "Permalink to this headline": "\u0421\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u044d\u0442\u043e\u0442 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a", "Collapse sidebar": ""}}); \ No newline at end of file +Documentation.addTranslations({"locale": "ru", "plural_expr": "(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)", "messages": {"Hide Search Matches": "\u0421\u043d\u044f\u0442\u044c \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u0438\u0435", "Permalink to this definition": "\u0421\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u044d\u0442\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435", "Expand sidebar": "\u0420\u0430\u0437\u0432\u0435\u0440\u043d\u0443\u0442\u044c \u0431\u043e\u043a\u043e\u0432\u0443\u044e \u043f\u0430\u043d\u0435\u043b\u044c", "Permalink to this headline": "\u0421\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u044d\u0442\u043e\u0442 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a", "Collapse sidebar": "\u0421\u0432\u0435\u0440\u043d\u0443\u0442\u044c \u0431\u043e\u043a\u043e\u0432\u0443\u044e \u043f\u0430\u043d\u0435\u043b\u044c"}}); \ No newline at end of file diff --git a/sphinx/locale/ru/LC_MESSAGES/sphinx.mo b/sphinx/locale/ru/LC_MESSAGES/sphinx.mo index 593350d31..5a0cabce9 100644 Binary files a/sphinx/locale/ru/LC_MESSAGES/sphinx.mo and b/sphinx/locale/ru/LC_MESSAGES/sphinx.mo differ diff --git a/sphinx/locale/ru/LC_MESSAGES/sphinx.po b/sphinx/locale/ru/LC_MESSAGES/sphinx.po index b6374d813..2e10a31f6 100644 --- a/sphinx/locale/ru/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/ru/LC_MESSAGES/sphinx.po @@ -1,21 +1,20 @@ -# Russian translations for Sphinx. -# Copyright (C) 2008 ORGANIZATION -# This file is distributed under the same license as the Sphinx project. +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. # msgid "" msgstr "" -"Project-Id-Version: Sphinx 0.6b1\n" -"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2011-09-21 10:06+0200\n" -"PO-Revision-Date: 2011-09-21 10:14+0200\n" -"Last-Translator: alexander smishlajev \n" -"Language-Team: ru \n" -"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && " -"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2\n" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-08-12 21:48+0700\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" "MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=utf-8\n" +"Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 0.9.6\n" #: sphinx/config.py:81 #, python-format @@ -24,21 +23,22 @@ msgstr "" #: sphinx/environment.py:119 sphinx/writers/latex.py:190 #: sphinx/writers/manpage.py:67 sphinx/writers/texinfo.py:203 +#: sphinx/writers/latex.py:191 sphinx/environment.py:113 #, python-format msgid "%B %d, %Y" msgstr "%d %B %Y" -#: sphinx/environment.py:1625 +#: sphinx/environment.py:1625 sphinx/environment.py:1638 #, python-format msgid "see %s" msgstr "" -#: sphinx/environment.py:1628 +#: sphinx/environment.py:1628 sphinx/environment.py:1641 #, python-format msgid "see also %s" msgstr "" -#: sphinx/roles.py:175 +#: sphinx/roles.py:175 sphinx/roles.py:176 #, fuzzy, python-format msgid "Python Enhancement Proposals; PEP %s" msgstr "Python Enhancement Proposals; PEP %s" @@ -51,24 +51,25 @@ msgstr "Встроенные функции" msgid "Module level" msgstr "Модуль" -#: sphinx/builders/html.py:274 +#: sphinx/builders/html.py:274 sphinx/builders/html.py:276 #, python-format msgid "%b %d, %Y" msgstr "%d %b %Y" #: sphinx/builders/html.py:293 sphinx/themes/basic/defindex.html:30 +#: sphinx/builders/html.py:295 msgid "General Index" -msgstr "Словарь-указатель" +msgstr "Алфавитный указатель" -#: sphinx/builders/html.py:293 +#: sphinx/builders/html.py:293 sphinx/builders/html.py:295 msgid "index" -msgstr "словарь" +msgstr "указатель" -#: sphinx/builders/html.py:353 +#: sphinx/builders/html.py:353 sphinx/builders/html.py:355 msgid "next" msgstr "следующий" -#: sphinx/builders/html.py:362 +#: sphinx/builders/html.py:362 sphinx/builders/html.py:364 msgid "previous" msgstr "предыдущий" @@ -76,24 +77,24 @@ msgstr "предыдущий" msgid " (in " msgstr " (в " -#: sphinx/directives/other.py:136 +#: sphinx/directives/other.py:136 sphinx/directives/other.py:138 msgid "Section author: " -msgstr "Автор секции: " +msgstr "Автор раздела: " -#: sphinx/directives/other.py:138 +#: sphinx/directives/other.py:138 sphinx/directives/other.py:140 msgid "Module author: " msgstr "Автор модуля: " -#: sphinx/directives/other.py:140 +#: sphinx/directives/other.py:140 sphinx/directives/other.py:142 #, fuzzy msgid "Code author: " msgstr "Автор модуля: " -#: sphinx/directives/other.py:142 +#: sphinx/directives/other.py:142 sphinx/directives/other.py:144 msgid "Author: " msgstr "Автор: " -#: sphinx/directives/other.py:215 +#: sphinx/directives/other.py:215 sphinx/directives/other.py:219 msgid "See also" msgstr "См.также" @@ -162,22 +163,22 @@ msgstr "тип" msgid "variable" msgstr "Переменная" -#: sphinx/domains/cpp.py:904 +#: sphinx/domains/cpp.py:904 sphinx/domains/cpp.py:1020 #, python-format msgid "%s (C++ class)" msgstr "%s (класс C++)" -#: sphinx/domains/cpp.py:919 +#: sphinx/domains/cpp.py:919 sphinx/domains/cpp.py:1043 #, python-format msgid "%s (C++ type)" msgstr "%s (тип C++)" -#: sphinx/domains/cpp.py:938 +#: sphinx/domains/cpp.py:938 sphinx/domains/cpp.py:1063 #, python-format msgid "%s (C++ member)" msgstr "%s (поле C++)" -#: sphinx/domains/cpp.py:990 +#: sphinx/domains/cpp.py:990 sphinx/domains/cpp.py:1119 #, python-format msgid "%s (C++ function)" msgstr "%s (функция C++)" @@ -188,11 +189,13 @@ msgid "class" msgstr "класс" #: sphinx/domains/javascript.py:106 sphinx/domains/python.py:254 +#: sphinx/domains/python.py:253 #, python-format msgid "%s() (built-in function)" msgstr "%s() (встроенная функция)" #: sphinx/domains/javascript.py:107 sphinx/domains/python.py:318 +#: sphinx/domains/python.py:317 #, python-format msgid "%s() (%s method)" msgstr "%s() (метод %s)" @@ -208,6 +211,7 @@ msgid "%s (global variable or constant)" msgstr "" #: sphinx/domains/javascript.py:113 sphinx/domains/python.py:356 +#: sphinx/domains/python.py:355 #, python-format msgid "%s (%s attribute)" msgstr "%s (атрибут %s)" @@ -240,56 +244,59 @@ msgstr "Исключение" #: sphinx/domains/python.py:255 sphinx/domains/python.py:312 #: sphinx/domains/python.py:324 sphinx/domains/python.py:337 +#: sphinx/domains/python.py:254 sphinx/domains/python.py:311 +#: sphinx/domains/python.py:323 sphinx/domains/python.py:336 #, python-format msgid "%s() (in module %s)" msgstr "%s() (в модуле %s)" -#: sphinx/domains/python.py:258 +#: sphinx/domains/python.py:258 sphinx/domains/python.py:257 #, python-format msgid "%s (built-in variable)" msgstr "%s (встроенная переменная)" #: sphinx/domains/python.py:259 sphinx/domains/python.py:350 +#: sphinx/domains/python.py:258 sphinx/domains/python.py:349 #, python-format msgid "%s (in module %s)" msgstr "%s (в модуле %s)" -#: sphinx/domains/python.py:275 +#: sphinx/domains/python.py:275 sphinx/domains/python.py:274 #, python-format msgid "%s (built-in class)" msgstr "%s (встроенный класс)" -#: sphinx/domains/python.py:276 +#: sphinx/domains/python.py:276 sphinx/domains/python.py:275 #, python-format msgid "%s (class in %s)" msgstr "%s (класс в %s)" -#: sphinx/domains/python.py:316 +#: sphinx/domains/python.py:316 sphinx/domains/python.py:315 #, python-format msgid "%s() (%s.%s method)" msgstr "%s() (метод %s.%s)" -#: sphinx/domains/python.py:328 +#: sphinx/domains/python.py:328 sphinx/domains/python.py:327 #, python-format msgid "%s() (%s.%s static method)" msgstr "%s() (статический метод %s.%s)" -#: sphinx/domains/python.py:331 +#: sphinx/domains/python.py:331 sphinx/domains/python.py:330 #, python-format msgid "%s() (%s static method)" msgstr "%s() (статический метод %s)" -#: sphinx/domains/python.py:341 +#: sphinx/domains/python.py:341 sphinx/domains/python.py:340 #, fuzzy, python-format msgid "%s() (%s.%s class method)" msgstr "%s() (метод %s.%s)" -#: sphinx/domains/python.py:344 +#: sphinx/domains/python.py:344 sphinx/domains/python.py:343 #, fuzzy, python-format msgid "%s() (%s class method)" msgstr "%s() (метод %s)" -#: sphinx/domains/python.py:354 +#: sphinx/domains/python.py:354 sphinx/domains/python.py:353 #, python-format msgid "%s (%s.%s attribute)" msgstr "%s (атрибут %s.%s)" @@ -308,7 +315,7 @@ msgstr "Состав модуля" msgid "modules" msgstr "модули" -#: sphinx/domains/python.py:537 +#: sphinx/domains/python.py:537 sphinx/domains/python.py:538 msgid "Deprecated" msgstr "Не рекомендуется" @@ -332,17 +339,17 @@ msgstr "статический метод" msgid "module" msgstr "модуль" -#: sphinx/domains/python.py:695 +#: sphinx/domains/python.py:695 sphinx/domains/python.py:696 #, fuzzy msgid " (deprecated)" msgstr " (не рекомендуется)" -#: sphinx/domains/rst.py:55 +#: sphinx/domains/rst.py:55 sphinx/domains/rst.py:53 #, python-format msgid "%s (directive)" msgstr "" -#: sphinx/domains/rst.py:57 +#: sphinx/domains/rst.py:57 sphinx/domains/rst.py:55 #, python-format msgid "%s (role)" msgstr "" @@ -391,6 +398,7 @@ msgstr "" #: sphinx/themes/basic/genindex.html:32 sphinx/themes/basic/genindex.html:35 #: sphinx/themes/basic/genindex.html:68 sphinx/themes/basic/layout.html:134 #: sphinx/writers/latex.py:179 sphinx/writers/texinfo.py:456 +#: sphinx/writers/latex.py:180 msgid "Index" msgstr "Алфавитный указатель" @@ -402,36 +410,36 @@ msgstr "Состав модуля" msgid "Search Page" msgstr "Поиск" -#: sphinx/ext/autodoc.py:1002 +#: sphinx/ext/autodoc.py:1002 sphinx/ext/autodoc.py:1010 #, python-format msgid " Bases: %s" msgstr " Базовые классы: %s" -#: sphinx/ext/autodoc.py:1038 +#: sphinx/ext/autodoc.py:1038 sphinx/ext/autodoc.py:1046 #, python-format msgid "alias of :class:`%s`" msgstr "псевдоним класса :class:`%s`" -#: sphinx/ext/todo.py:41 +#: sphinx/ext/todo.py:41 sphinx/ext/todo.py:42 msgid "Todo" msgstr "План" -#: sphinx/ext/todo.py:109 +#: sphinx/ext/todo.py:109 sphinx/ext/todo.py:110 #, fuzzy, python-format msgid "(The <> is located in %s, line %d.)" msgstr "(Исходный элемент находится в %s, в строке %d.)" -#: sphinx/ext/todo.py:117 +#: sphinx/ext/todo.py:117 sphinx/ext/todo.py:119 msgid "original entry" msgstr "" #: sphinx/ext/viewcode.py:70 msgid "[source]" -msgstr "" +msgstr "[исходный код]" #: sphinx/ext/viewcode.py:117 msgid "[docs]" -msgstr "" +msgstr "[документация]" #: sphinx/ext/viewcode.py:131 #, fuzzy @@ -441,15 +449,15 @@ msgstr "модуль" #: sphinx/ext/viewcode.py:137 #, python-format msgid "

        Source code for %s

        " -msgstr "" +msgstr "

        Исходный код %s

        " #: sphinx/ext/viewcode.py:164 msgid "Overview: module code" -msgstr "" +msgstr "Обзор: исходный код модуля" #: sphinx/ext/viewcode.py:165 msgid "

        All modules for which code is available

        " -msgstr "" +msgstr "

        Все модули, в которых есть код

        " #: sphinx/locale/__init__.py:155 msgid "Attention" @@ -481,7 +489,7 @@ msgstr "Примечание" #: sphinx/locale/__init__.py:162 msgid "See Also" -msgstr "См.также" +msgstr "См. также" #: sphinx/locale/__init__.py:163 msgid "Tip" @@ -529,7 +537,7 @@ msgstr "базовая функция" #: sphinx/themes/agogo/layout.html:45 sphinx/themes/basic/globaltoc.html:10 #: sphinx/themes/basic/localtoc.html:11 msgid "Table Of Contents" -msgstr "Содержание" +msgstr "Оглавление" #: sphinx/themes/agogo/layout.html:49 sphinx/themes/basic/layout.html:137 #: sphinx/themes/basic/search.html:11 sphinx/themes/basic/search.html:20 @@ -546,7 +554,7 @@ msgstr "Введите слова для поиска или имя модуля #: sphinx/themes/agogo/layout.html:78 sphinx/themes/basic/sourcelink.html:14 msgid "Show Source" -msgstr "Показать исходный текст" +msgstr "Исходный текст" #: sphinx/themes/basic/defindex.html:11 msgid "Overview" @@ -558,7 +566,7 @@ msgstr "Таблицы и указатели:" #: sphinx/themes/basic/defindex.html:23 msgid "Complete Table of Contents" -msgstr "Подробное оглавление" +msgstr "Полное оглавление" #: sphinx/themes/basic/defindex.html:24 msgid "lists all sections and subsections" @@ -566,7 +574,7 @@ msgstr "список всех разделов и подразделов" #: sphinx/themes/basic/defindex.html:26 msgid "search this documentation" -msgstr "поиск во всем документе" +msgstr "поиск в документации" #: sphinx/themes/basic/defindex.html:28 msgid "Global Module Index" @@ -611,16 +619,16 @@ msgstr "Поиск в документе «%(docstitle)s»" #: sphinx/themes/basic/layout.html:131 msgid "About these documents" -msgstr "Об этих документах…" +msgstr "Об этих документах" #: sphinx/themes/basic/layout.html:140 msgid "Copyright" -msgstr "Copyright" +msgstr "Авторские права" #: sphinx/themes/basic/layout.html:189 #, python-format msgid "© Copyright %(copyright)s." -msgstr "© Copyright %(copyright)s." +msgstr "© Авторские права %(copyright)s." #: sphinx/themes/basic/layout.html:191 #, python-format @@ -630,15 +638,15 @@ msgstr "© Copyright %(copyright)s." #: sphinx/themes/basic/layout.html:195 #, python-format msgid "Last updated on %(last_updated)s." -msgstr "Дата последнего обновления: %(last_updated)s." +msgstr "Обновлено: %(last_updated)s." #: sphinx/themes/basic/layout.html:198 #, python-format msgid "" -"Created using Sphinx " +"Created using Sphinx " "%(sphinx_version)s." msgstr "" -"При создании использован Sphinx " +"Создано с помощью Sphinx " "%(sphinx_version)s." #: sphinx/themes/basic/opensearch.xml:4 @@ -666,7 +674,7 @@ msgstr "следующая глава" msgid "" "Please activate JavaScript to enable the search\n" " functionality." -msgstr "Для выполнения поиска необходима поддержка JavaScript в браузере." +msgstr "Для работы поиска включите JavaScript в браузере." #: sphinx/themes/basic/search.html:29 msgid "" @@ -675,11 +683,10 @@ msgid "" " function will automatically search for all of the words. Pages\n" " containing fewer words won't appear in the result list." msgstr "" -"Эта форма предназначена для поиска по всем разделам настоящей " -"документации. Введите искомые слова в текстовое поле и нажмите кнопку " -"«искать». Обратите внимание: найдены будут только те страницы, в которых " -"упомянуты все указанные слова. Страницы, в которых встречается только " -"часть этих слов, отобраны не будут." +"Здесь можно делать поиск по всем разделам этой документации. Введите " +" ключевые слова в текстовое поле и нажмите кнопку «искать». Внимание: будут " +" найдены только те страницы, в которых есть все указанные слова. Страницы, " +" где есть только часть этих слов, отобраны не будут." #: sphinx/themes/basic/search.html:36 msgid "search" @@ -691,7 +698,7 @@ msgstr "Результаты поиска" #: sphinx/themes/basic/search.html:42 msgid "Your search did not match any results." -msgstr "Результатов по вашему запросу не найдено." +msgstr "Страниц по вашему запросу не найдено." #: sphinx/themes/basic/searchbox.html:12 msgid "Quick search" @@ -723,18 +730,19 @@ msgstr "Изменения в библиотеке" #: sphinx/themes/basic/changes/versionchanges.html:23 msgid "C API changes" -msgstr "Изменения в C API" +msgstr "Изменения в API C" #: sphinx/themes/basic/changes/versionchanges.html:25 msgid "Other changes" msgstr "Другие изменения" #: sphinx/themes/basic/static/doctools.js:154 sphinx/writers/html.py:504 -#: sphinx/writers/html.py:510 +#: sphinx/writers/html.py:510 sphinx/writers/html.py:516 msgid "Permalink to this headline" msgstr "Ссылка на этот заголовок" #: sphinx/themes/basic/static/doctools.js:160 sphinx/writers/html.py:92 +#: sphinx/writers/html.py:94 msgid "Permalink to this definition" msgstr "Ссылка на это определение" @@ -744,36 +752,55 @@ msgstr "Снять выделение" #: sphinx/themes/default/static/sidebar.js:69 msgid "Expand sidebar" -msgstr "" +msgstr "Развернуть боковую панель" #: sphinx/themes/default/static/sidebar.js:82 #: sphinx/themes/default/static/sidebar.js:110 msgid "Collapse sidebar" -msgstr "" +msgstr "Свернуть боковую панель" #: sphinx/themes/haiku/layout.html:26 msgid "Contents" -msgstr "" +msgstr "Содержание" -#: sphinx/writers/latex.py:177 +#: sphinx/writers/latex.py:177 sphinx/writers/latex.py:178 msgid "Release" msgstr "Выпуск" #: sphinx/writers/latex.py:594 sphinx/writers/manpage.py:182 -#: sphinx/writers/texinfo.py:589 +#: sphinx/writers/texinfo.py:589 sphinx/writers/latex.py:601 msgid "Footnotes" -msgstr "" +msgstr "Сноски" -#: sphinx/writers/latex.py:676 +#: sphinx/writers/latex.py:676 sphinx/writers/latex.py:685 msgid "continued from previous page" -msgstr "" +msgstr "продолжение с предыдущей страницы" -#: sphinx/writers/latex.py:681 +#: sphinx/writers/latex.py:681 sphinx/writers/latex.py:691 #, fuzzy msgid "Continued on next page" -msgstr "Полный алфавитный указатель на одной странице" +msgstr "Продолжается на следующей странице" -#: sphinx/writers/text.py:437 +#: sphinx/writers/text.py:437 sphinx/writers/manpage.py:234 +#: sphinx/writers/text.py:439 msgid "[image]" msgstr "[рисунок]" +#: sphinx/writers/manpage.py:233 sphinx/writers/text.py:438 +#, python-format +msgid "[image: %s]" +msgstr "[рисунок: %s]" + +#: sphinx/ext/graphviz.py:302 sphinx/ext/graphviz.py:310 +#, python-format +msgid "[graph: %s]" +msgstr "[иллюстрация: %s]" + +#: sphinx/ext/graphviz.py:304 sphinx/ext/graphviz.py:312 +msgid "[graph]" +msgstr "[иллюстрация]" + +#: sphinx/ext/intersphinx.py:224 +#, python-format +msgid "(in %s v%s)" +msgstr "" diff --git a/sphinx/locale/sk/LC_MESSAGES/sphinx.js b/sphinx/locale/sk/LC_MESSAGES/sphinx.js index 2d210b548..9c2d6a75f 100644 --- a/sphinx/locale/sk/LC_MESSAGES/sphinx.js +++ b/sphinx/locale/sk/LC_MESSAGES/sphinx.js @@ -1 +1 @@ -Documentation.addTranslations({"locale": "sk", "plural_expr": "(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)", "messages": {"Hide Search Matches": "Skr\u00fdt v\u00fdsledky vyhled\u00e1v\u00e1n\u00ed", "Permalink to this definition": "Trval\u00fd odkaz na tuto definici", "Expand sidebar": "", "Permalink to this headline": "Trval\u00fd odkaz na tento nadpis", "Collapse sidebar": ""}}); +Documentation.addTranslations({"locale": "sk", "plural_expr": "(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)", "messages": {"Hide Search Matches": "Skry\u0165 v\u00fdsledky vyh\u013ead\u00e1vania", "Permalink to this definition": "Trval\u00fd odkaz na t\u00fato defin\u00edciu", "Expand sidebar": "", "Permalink to this headline": "Trval\u00fd odkaz na tento nadpis", "Collapse sidebar": ""}}); \ No newline at end of file diff --git a/sphinx/locale/sk/LC_MESSAGES/sphinx.mo b/sphinx/locale/sk/LC_MESSAGES/sphinx.mo index 8a4ac3a87..375159dc2 100644 Binary files a/sphinx/locale/sk/LC_MESSAGES/sphinx.mo and b/sphinx/locale/sk/LC_MESSAGES/sphinx.mo differ diff --git a/sphinx/locale/sk/LC_MESSAGES/sphinx.po b/sphinx/locale/sk/LC_MESSAGES/sphinx.po index 77f120232..fdc5e1371 100644 --- a/sphinx/locale/sk/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/sk/LC_MESSAGES/sphinx.po @@ -635,10 +635,10 @@ msgstr "Aktualizované dňa %(last_updated)s." #: sphinx/themes/basic/layout.html:198 #, python-format msgid "" -"Created using Sphinx " +"Created using Sphinx " "%(sphinx_version)s." msgstr "" -"Vytvorené pomocou Sphinx " +"Vytvorené pomocou Sphinx " "%(sphinx_version)s." #: sphinx/themes/basic/opensearch.xml:4 diff --git a/sphinx/locale/sl/LC_MESSAGES/sphinx.mo b/sphinx/locale/sl/LC_MESSAGES/sphinx.mo index 79f7f4eb3..a4fe3d63a 100644 Binary files a/sphinx/locale/sl/LC_MESSAGES/sphinx.mo and b/sphinx/locale/sl/LC_MESSAGES/sphinx.mo differ diff --git a/sphinx/locale/sl/LC_MESSAGES/sphinx.po b/sphinx/locale/sl/LC_MESSAGES/sphinx.po index 6f6e49aca..297d1cdba 100644 --- a/sphinx/locale/sl/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/sl/LC_MESSAGES/sphinx.po @@ -630,10 +630,10 @@ msgstr "Zadnjič posodobljeno %(last_updated)s." #: sphinx/themes/basic/layout.html:198 #, python-format msgid "" -"Created using Sphinx " +"Created using Sphinx " "%(sphinx_version)s." msgstr "" -"Narejeno s Sphinx " +"Narejeno s Sphinx " "%(sphinx_version)s." #: sphinx/themes/basic/opensearch.xml:4 diff --git a/sphinx/locale/sphinx.pot b/sphinx/locale/sphinx.pot index 9ddde4c26..b1d816f72 100644 --- a/sphinx/locale/sphinx.pot +++ b/sphinx/locale/sphinx.pot @@ -628,7 +628,7 @@ msgstr "" #: sphinx/themes/basic/layout.html:198 #, python-format msgid "" -"Created using Sphinx " +"Created using Sphinx " "%(sphinx_version)s." msgstr "" diff --git a/sphinx/locale/sv/LC_MESSAGES/sphinx.mo b/sphinx/locale/sv/LC_MESSAGES/sphinx.mo index 11b18023b..40280d85d 100644 Binary files a/sphinx/locale/sv/LC_MESSAGES/sphinx.mo and b/sphinx/locale/sv/LC_MESSAGES/sphinx.mo differ diff --git a/sphinx/locale/sv/LC_MESSAGES/sphinx.po b/sphinx/locale/sv/LC_MESSAGES/sphinx.po index 9967bdd74..6d0ed166e 100644 --- a/sphinx/locale/sv/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/sv/LC_MESSAGES/sphinx.po @@ -625,10 +625,10 @@ msgstr "Senast uppdaterad %(last_updated)s." #: sphinx/themes/basic/layout.html:198 #, python-format msgid "" -"Created using Sphinx " +"Created using Sphinx " "%(sphinx_version)s." msgstr "" -"Skapad med Sphinx " +"Skapad med Sphinx " "%(sphinx_version)s." #: sphinx/themes/basic/opensearch.xml:4 diff --git a/sphinx/locale/tr/LC_MESSAGES/sphinx.mo b/sphinx/locale/tr/LC_MESSAGES/sphinx.mo index 812b7cd94..2bf9e7a33 100644 Binary files a/sphinx/locale/tr/LC_MESSAGES/sphinx.mo and b/sphinx/locale/tr/LC_MESSAGES/sphinx.mo differ diff --git a/sphinx/locale/tr/LC_MESSAGES/sphinx.po b/sphinx/locale/tr/LC_MESSAGES/sphinx.po index bf5fd568c..cd8d7395e 100644 --- a/sphinx/locale/tr/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/tr/LC_MESSAGES/sphinx.po @@ -628,10 +628,10 @@ msgstr "Son güncelleme: %(last_updated)s." #: sphinx/themes/basic/layout.html:198 #, python-format msgid "" -"Created using Sphinx " +"Created using Sphinx " "%(sphinx_version)s." msgstr "" -"Sphinx %(sphinx_version)s ile " +"Sphinx %(sphinx_version)s ile " "oluşturulmuştur." #: sphinx/themes/basic/opensearch.xml:4 diff --git a/sphinx/locale/uk_UA/LC_MESSAGES/sphinx.mo b/sphinx/locale/uk_UA/LC_MESSAGES/sphinx.mo index 4bc58ee1e..5fa633d36 100644 Binary files a/sphinx/locale/uk_UA/LC_MESSAGES/sphinx.mo and b/sphinx/locale/uk_UA/LC_MESSAGES/sphinx.mo differ diff --git a/sphinx/locale/uk_UA/LC_MESSAGES/sphinx.po b/sphinx/locale/uk_UA/LC_MESSAGES/sphinx.po index 32ce1dc4a..a5141fad5 100644 --- a/sphinx/locale/uk_UA/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/uk_UA/LC_MESSAGES/sphinx.po @@ -635,10 +635,10 @@ msgstr "Востаннє оновлено %(last_updated)s." #: sphinx/themes/basic/layout.html:198 #, python-format msgid "" -"Created using Sphinx " +"Created using Sphinx " "%(sphinx_version)s." msgstr "" -"Створено з використанням Sphinx " +"Створено з використанням Sphinx " "%(sphinx_version)s." #: sphinx/themes/basic/opensearch.xml:4 diff --git a/sphinx/locale/zh_CN/LC_MESSAGES/sphinx.mo b/sphinx/locale/zh_CN/LC_MESSAGES/sphinx.mo index 3d9dac2ba..eb5b0763f 100644 Binary files a/sphinx/locale/zh_CN/LC_MESSAGES/sphinx.mo and b/sphinx/locale/zh_CN/LC_MESSAGES/sphinx.mo differ diff --git a/sphinx/locale/zh_CN/LC_MESSAGES/sphinx.po b/sphinx/locale/zh_CN/LC_MESSAGES/sphinx.po index cb7b3e6f2..079bab5e8 100644 --- a/sphinx/locale/zh_CN/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/zh_CN/LC_MESSAGES/sphinx.po @@ -636,9 +636,9 @@ msgstr "最后更新日期是 %(last_updated)s." #: sphinx/themes/basic/layout.html:198 #, python-format msgid "" -"Created using Sphinx " +"Created using Sphinx " "%(sphinx_version)s." -msgstr "使用 Sphinx %(sphinx_version)s." +msgstr "使用 Sphinx %(sphinx_version)s." #: sphinx/themes/basic/opensearch.xml:4 #, python-format diff --git a/sphinx/locale/zh_TW/LC_MESSAGES/sphinx.mo b/sphinx/locale/zh_TW/LC_MESSAGES/sphinx.mo index 9dd86da5d..98c5d6e82 100644 Binary files a/sphinx/locale/zh_TW/LC_MESSAGES/sphinx.mo and b/sphinx/locale/zh_TW/LC_MESSAGES/sphinx.mo differ diff --git a/sphinx/locale/zh_TW/LC_MESSAGES/sphinx.po b/sphinx/locale/zh_TW/LC_MESSAGES/sphinx.po index 2a4fbef09..5d178af1f 100644 --- a/sphinx/locale/zh_TW/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/zh_TW/LC_MESSAGES/sphinx.po @@ -638,7 +638,7 @@ msgstr "最後更新日期是 %(last_updated)s." #: sphinx/themes/basic/layout.html:198 #, python-format msgid "" -"Created using Sphinx " +"Created using Sphinx " "%(sphinx_version)s." msgstr "" diff --git a/sphinx/pycode/__init__.py b/sphinx/pycode/__init__.py index ef626f6d1..073c1560d 100644 --- a/sphinx/pycode/__init__.py +++ b/sphinx/pycode/__init__.py @@ -5,7 +5,7 @@ Utilities parsing and analyzing Python code. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/pycode/nodes.py b/sphinx/pycode/nodes.py index 7adacc1d0..c1feb5b13 100644 --- a/sphinx/pycode/nodes.py +++ b/sphinx/pycode/nodes.py @@ -5,7 +5,7 @@ Parse tree node implementations. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/pygments_styles.py b/sphinx/pygments_styles.py index 44740b31e..a8b0f123f 100644 --- a/sphinx/pygments_styles.py +++ b/sphinx/pygments_styles.py @@ -5,7 +5,7 @@ Sphinx theme specific highlighting styles. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/quickstart.py b/sphinx/quickstart.py index c8dd2579c..0c7677c51 100644 --- a/sphinx/quickstart.py +++ b/sphinx/quickstart.py @@ -5,13 +5,12 @@ Quickly setup documentation source to work with Sphinx. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ import sys, os, time, re from os import path -from codecs import open TERM_ENCODING = getattr(sys.stdin, 'encoding', None) @@ -20,6 +19,7 @@ from sphinx.util.osutil import make_filename from sphinx.util.console import purple, bold, red, turquoise, \ nocolor, color_terminal from sphinx.util import texescape +from sphinx.util.pycompat import open # function to get input from terminal -- overridden by the test suite try: @@ -33,11 +33,11 @@ PROMPT_PREFIX = '> ' if sys.version_info >= (3, 0): # prevents that the file is checked for being written in Python 2.x syntax - QUICKSTART_CONF = '#!/usr/bin/env python3\n' + QUICKSTART_CONF = u'#!/usr/bin/env python3\n' else: - QUICKSTART_CONF = '' + QUICKSTART_CONF = u'' -QUICKSTART_CONF += '''\ +QUICKSTART_CONF += u'''\ # -*- coding: utf-8 -*- # # %(project)s documentation build configuration file, created by @@ -282,7 +282,7 @@ texinfo_documents = [ #texinfo_show_urls = 'footnote' ''' -EPUB_CONFIG = ''' +EPUB_CONFIG = u''' # -- Options for Epub output --------------------------------------------------- @@ -334,15 +334,18 @@ epub_copyright = u'%(copyright_str)s' # Scale large images. #epub_max_image_width = 0 + +# If 'no', URL addresses will not be shown. +#epub_show_urls = 'inline' ''' -INTERSPHINX_CONFIG = ''' +INTERSPHINX_CONFIG = u''' # Example configuration for intersphinx: refer to the Python standard library. intersphinx_mapping = {'http://docs.python.org/': None} ''' -MASTER_FILE = '''\ +MASTER_FILE = u'''\ .. %(project)s documentation master file, created by sphinx-quickstart on %(now)s. You can adapt this file completely to your liking, but it should at least @@ -367,7 +370,7 @@ Indices and tables ''' -MAKEFILE = '''\ +MAKEFILE = u'''\ # Makefile for Sphinx documentation # @@ -377,6 +380,21 @@ SPHINXBUILD = sphinx-build PAPER = BUILDDIR = %(rbuilddir)s +ifeq ($(shell $(SPHINXBUILD) 2> /dev/null; echo $$?), 127) +define MSG + + +The 'sphinx-build' command was not found. Make sure you have Sphinx +installed, then set the SPHINXBUILD environment variable to point +to the full path of the 'sphinx-build' executable. Alternatively you +may add the Sphinx directory to PATH. + +If you don't have Sphinx installed, grab it from +http://sphinx-doc.org/ +endef +$(error $(MSG)) +endif + # Internal variables. PAPEROPT_a4 = -D latex_paper_size=a4 PAPEROPT_letter = -D latex_paper_size=letter @@ -401,18 +419,21 @@ help: \t@echo " epub to make an epub" \t@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" \t@echo " latexpdf to make LaTeX files and run them through pdflatex" +\t@echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" \t@echo " text to make text files" \t@echo " man to make manual pages" \t@echo " texinfo to make Texinfo files" \t@echo " info to make Texinfo files and run them through makeinfo" \t@echo " gettext to make PO message catalogs" \t@echo " changes to make an overview of all changed/added/deprecated items" +\t@echo " xml to make Docutils-native XML files" +\t@echo " pseudoxml to make pseudoxml-XML files for display purposes" \t@echo " linkcheck to check all external links for integrity" \t@echo " doctest to run all doctests embedded in the documentation \ (if enabled)" clean: -\t-rm -rf $(BUILDDIR)/* +\trm -rf $(BUILDDIR)/* html: \t$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html @@ -482,6 +503,12 @@ latexpdf: \t$(MAKE) -C $(BUILDDIR)/latex all-pdf \t@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." +latexpdfja: +\t$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex +\t@echo "Running LaTeX files through platex and dvipdfmx..." +\t$(MAKE) -C $(BUILDDIR)/latex all-pdf-ja +\t@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + text: \t$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text \t@echo @@ -525,9 +552,19 @@ doctest: \t$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest \t@echo "Testing of doctests in the sources finished, look at the " \\ \t "results in $(BUILDDIR)/doctest/output.txt." + +xml: +\t$(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml +\t@echo +\t@echo "Build finished. The XML files are in $(BUILDDIR)/xml." + +pseudoxml: +\t$(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml +\t@echo +\t@echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." ''' -BATCHFILE = '''\ +BATCHFILE = u'''\ @ECHO OFF REM Command file for Sphinx documentation @@ -563,6 +600,8 @@ if "%%1" == "help" ( \techo. texinfo to make Texinfo files \techo. gettext to make PO message catalogs \techo. changes to make an overview over all changed/added/deprecated items +\techo. xml to make Docutils-native XML files +\techo. pseudoxml to make pseudoxml-XML files for display purposes \techo. linkcheck to check all external links for integrity \techo. doctest to run all doctests embedded in the documentation if enabled \tgoto end @@ -574,6 +613,20 @@ if "%%1" == "clean" ( \tgoto end ) + +%%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 +) + if "%%1" == "html" ( \t%%SPHINXBUILD%% -b html %%ALLSPHINXOPTS%% %%BUILDDIR%%/html \tif errorlevel 1 exit /b 1 @@ -659,6 +712,26 @@ if "%%1" == "latex" ( \tgoto end ) +if "%%1" == "latexpdf" ( +\t%%SPHINXBUILD%% -b latex %%ALLSPHINXOPTS%% %%BUILDDIR%%/latex +\tcd %%BUILDDIR%%/latex +\tmake all-pdf +\tcd %%BUILDDIR%%/.. +\techo. +\techo.Build finished; the PDF files are in %%BUILDDIR%%/latex. +\tgoto end +) + +if "%%1" == "latexpdfja" ( +\t%%SPHINXBUILD%% -b latex %%ALLSPHINXOPTS%% %%BUILDDIR%%/latex +\tcd %%BUILDDIR%%/latex +\tmake all-pdf-ja +\tcd %%BUILDDIR%%/.. +\techo. +\techo.Build finished; the PDF files are in %%BUILDDIR%%/latex. +\tgoto end +) + if "%%1" == "text" ( \t%%SPHINXBUILD%% -b text %%ALLSPHINXOPTS%% %%BUILDDIR%%/text \tif errorlevel 1 exit /b 1 @@ -717,6 +790,22 @@ results in %%BUILDDIR%%/doctest/output.txt. \tgoto end ) +if "%%1" == "xml" ( +\t%%SPHINXBUILD%% -b xml %%ALLSPHINXOPTS%% %%BUILDDIR%%/xml +\tif errorlevel 1 exit /b 1 +\techo. +\techo.Build finished. The XML files are in %%BUILDDIR%%/xml. +\tgoto end +) + +if "%%1" == "pseudoxml" ( +\t%%SPHINXBUILD%% -b pseudoxml %%ALLSPHINXOPTS%% %%BUILDDIR%%/pseudoxml +\tif errorlevel 1 exit /b 1 +\techo. +\techo.Build finished. The pseudo-XML files are in %%BUILDDIR%%/pseudoxml. +\tgoto end +) + :end ''' @@ -768,7 +857,7 @@ def do_prompt(d, key, text, default=None, validator=nonempty): prompt = purple(PROMPT_PREFIX + '%s [%s]: ' % (text, default)) else: prompt = purple(PROMPT_PREFIX + text + ': ') - x = term_input(prompt) + x = term_input(prompt).strip() if default and not x: x = default if not isinstance(x, unicode): @@ -795,14 +884,13 @@ def do_prompt(d, key, text, default=None, validator=nonempty): if sys.version_info >= (3, 0): # remove Unicode literal prefixes - _unicode_string_re = re.compile(r"[uU]('.*?')") - def _convert_python_source(source): - return _unicode_string_re.sub('\\1', source) + def _convert_python_source(source, rex=re.compile(r"[uU]('.*?')")): + return rex.sub('\\1', source) for f in ['QUICKSTART_CONF', 'EPUB_CONFIG', 'INTERSPHINX_CONFIG']: globals()[f] = _convert_python_source(globals()[f]) - del _unicode_string_re, _convert_python_source + del _convert_python_source def ask_user(d): @@ -1008,10 +1096,10 @@ def generate(d, overwrite=True, silent=False): mkdir_p(path.join(srcdir, d['dot'] + 'templates')) mkdir_p(path.join(srcdir, d['dot'] + 'static')) - def write_file(fpath, mode, content): + def write_file(fpath, content, newline=None): if overwrite or not path.isfile(fpath): print 'Creating file %s.' % fpath - f = open(fpath, mode, encoding='utf-8') + f = open(fpath, 'wt', encoding='utf-8', newline=newline) try: f.write(content) finally: @@ -1025,21 +1113,21 @@ def generate(d, overwrite=True, silent=False): if d.get('ext_intersphinx'): conf_text += INTERSPHINX_CONFIG - write_file(path.join(srcdir, 'conf.py'), 'w', conf_text) + write_file(path.join(srcdir, 'conf.py'), conf_text) masterfile = path.join(srcdir, d['master'] + d['suffix']) - write_file(masterfile, 'w', MASTER_FILE % d) + write_file(masterfile, MASTER_FILE % d) if d['makefile']: d['rsrcdir'] = d['sep'] and 'source' or '.' d['rbuilddir'] = d['sep'] and 'build' or d['dot'] + 'build' # use binary mode, to avoid writing \r\n on Windows - write_file(path.join(d['path'], 'Makefile'), 'wb', MAKEFILE % d) + write_file(path.join(d['path'], 'Makefile'), MAKEFILE % d, u'\n') if d['batchfile']: d['rsrcdir'] = d['sep'] and 'source' or '.' d['rbuilddir'] = d['sep'] and 'build' or d['dot'] + 'build' - write_file(path.join(d['path'], 'make.bat'), 'w', BATCHFILE % d) + write_file(path.join(d['path'], 'make.bat'), BATCHFILE % d, u'\r\n') if silent: return diff --git a/sphinx/roles.py b/sphinx/roles.py index 312eec3f1..02c5ad8fc 100644 --- a/sphinx/roles.py +++ b/sphinx/roles.py @@ -5,7 +5,7 @@ Handlers for additional ReST roles. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ @@ -293,6 +293,7 @@ def index_role(typ, rawtext, text, lineno, inliner, options={}, content=[]): entries = [('single', target, targetid, main)] indexnode = addnodes.index() indexnode['entries'] = entries + set_role_source_info(inliner, lineno, indexnode) textnode = nodes.Text(title, title) return [indexnode, targetnode, textnode], [] diff --git a/sphinx/search/__init__.py b/sphinx/search/__init__.py index 6e9610a49..764c9208a 100644 --- a/sphinx/search/__init__.py +++ b/sphinx/search/__init__.py @@ -5,13 +5,15 @@ Create a full-text search index for offline search. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ +from __future__ import with_statement import re +import itertools import cPickle as pickle -from docutils.nodes import comment, Text, NodeVisitor, SkipNode +from docutils.nodes import comment, title, Text, NodeVisitor, SkipNode from sphinx.util import jsdump, rpartition @@ -92,6 +94,7 @@ var Stemmer = function() { (ord(word[0]) < 256 and (len(word) < 3 or word in self.stopwords or word.isdigit()))) + from sphinx.search import en, ja languages = { @@ -137,13 +140,16 @@ class WordCollector(NodeVisitor): def __init__(self, document, lang): NodeVisitor.__init__(self, document) self.found_words = [] + self.found_title_words = [] self.lang = lang def dispatch_visit(self, node): if node.__class__ is comment: raise SkipNode - if node.__class__ is Text: + elif node.__class__ is Text: self.found_words.extend(self.lang.split(node.astext())) + elif node.__class__ is title: + self.found_title_words.extend(self.lang.split(node.astext())) class IndexBuilder(object): @@ -156,12 +162,14 @@ class IndexBuilder(object): 'pickle': pickle } - def __init__(self, env, lang, options): + def __init__(self, env, lang, options, scoring): self.env = env # filename -> title self._titles = {} # stemmed word -> set(filenames) self._mapping = {} + # stemmed words in titles -> set(filenames) + self._title_mapping = {} # objtype -> index self._objtypes = {} # objtype index -> (domain, type, objname (localized)) @@ -169,6 +177,12 @@ class IndexBuilder(object): # add language-specific SearchLanguage instance self.lang = languages[lang](options) + if scoring: + with open(scoring, 'rb') as fp: + self.js_scorer_code = fp.read().decode('utf-8') + else: + self.js_scorer_code = u'' + def load(self, stream, format): """Reconstruct from frozen data.""" if isinstance(format, basestring): @@ -179,12 +193,18 @@ class IndexBuilder(object): raise ValueError('old format') index2fn = frozen['filenames'] self._titles = dict(zip(index2fn, frozen['titles'])) - self._mapping = {} - for k, v in frozen['terms'].iteritems(): - if isinstance(v, int): - self._mapping[k] = set([index2fn[v]]) - else: - self._mapping[k] = set(index2fn[i] for i in v) + + def load_terms(mapping): + rv = {} + for k, v in mapping.iteritems(): + if isinstance(v, int): + rv[k] = set([index2fn[v]]) + else: + rv[k] = set(index2fn[i] for i in v) + return rv + + self._mapping = load_terms(frozen['terms']) + self._title_mapping = load_terms(frozen['titleterms']) # no need to load keywords/objtypes def dump(self, stream, format): @@ -229,28 +249,31 @@ class IndexBuilder(object): return rv def get_terms(self, fn2index): - rv = {} - for k, v in self._mapping.iteritems(): - if len(v) == 1: - fn, = v - if fn in fn2index: - rv[k] = fn2index[fn] - else: - rv[k] = [fn2index[fn] for fn in v if fn in fn2index] - return rv + rvs = {}, {} + for rv, mapping in zip(rvs, (self._mapping, self._title_mapping)): + for k, v in mapping.iteritems(): + if len(v) == 1: + fn, = v + if fn in fn2index: + rv[k] = fn2index[fn] + else: + rv[k] = [fn2index[fn] for fn in v if fn in fn2index] + return rvs def freeze(self): """Create a usable data structure for serializing.""" filenames = self._titles.keys() titles = self._titles.values() fn2index = dict((f, i) for (i, f) in enumerate(filenames)) - terms = self.get_terms(fn2index) + terms, title_terms = self.get_terms(fn2index) + objects = self.get_objects(fn2index) # populates _objtypes objtypes = dict((v, k[0] + ':' + k[1]) for (k, v) in self._objtypes.iteritems()) objnames = self._objnames return dict(filenames=filenames, titles=titles, terms=terms, - objects=objects, objtypes=objtypes, objnames=objnames) + objects=objects, objtypes=objtypes, objnames=objnames, + titleterms=title_terms) def prune(self, filenames): """Remove data for all filenames not in the list.""" @@ -261,6 +284,8 @@ class IndexBuilder(object): self._titles = new_titles for wordnames in self._mapping.itervalues(): wordnames.intersection_update(filenames) + for wordnames in self._title_mapping.itervalues(): + wordnames.intersection_update(filenames) def feed(self, filename, title, doctree): """Feed a doctree to the index.""" @@ -269,19 +294,24 @@ class IndexBuilder(object): visitor = WordCollector(doctree, self.lang) doctree.walk(visitor) - def add_term(word, stem=self.lang.stem): - word = stem(word) - if self.lang.word_filter(word): - self._mapping.setdefault(word, set()).add(filename) + stem = self.lang.stem + _filter = self.lang.word_filter - for word in self.lang.split(title): - add_term(word) + for word in itertools.chain(visitor.found_title_words, + self.lang.split(title)): + word = stem(word) + if _filter(word): + self._title_mapping.setdefault(word, set()).add(filename) for word in visitor.found_words: - add_term(word) + word = stem(word) + if word not in self._title_mapping and _filter(word): + self._mapping.setdefault(word, set()).add(filename) def context_for_searchtool(self): return dict( search_language_stemming_code = self.lang.js_stemmer_code, - search_language_stop_words = jsdump.dumps(self.lang.stopwords), + search_language_stop_words = + jsdump.dumps(sorted(self.lang.stopwords)), + search_scorer_tool = self.js_scorer_code, ) diff --git a/sphinx/search/en.py b/sphinx/search/en.py index 1f3c3731f..9f3a9bf7d 100644 --- a/sphinx/search/en.py +++ b/sphinx/search/en.py @@ -5,7 +5,7 @@ English search language: includes the JS porter stemmer. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/search/ja.py b/sphinx/search/ja.py index 0a7d83a1c..c83c52efa 100644 --- a/sphinx/search/ja.py +++ b/sphinx/search/ja.py @@ -5,7 +5,7 @@ Japanese search language: includes routine to split words. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/setup_command.py b/sphinx/setup_command.py index 2a8b2ed2c..70358bbbc 100644 --- a/sphinx/setup_command.py +++ b/sphinx/setup_command.py @@ -8,7 +8,7 @@ :author: Sebastian Wiesner :contact: basti.wiesner@gmx.net - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/texinputs/Makefile b/sphinx/texinputs/Makefile index 76e7c3e25..6b87ad881 100644 --- a/sphinx/texinputs/Makefile +++ b/sphinx/texinputs/Makefile @@ -16,11 +16,11 @@ all-ps: all-dvi for f in *.dvi; do dvips $$f; done all-pdf-ja: - for f in *.pdf *.png *.gif *.jpg *.jpeg; do ebb $$f; done + for f in *.pdf *.png *.gif *.jpg *.jpeg; do extractbb $$f; done for f in *.tex; do platex -kanji=utf8 $(LATEXOPTS) $$f; done for f in *.tex; do platex -kanji=utf8 $(LATEXOPTS) $$f; done for f in *.tex; do platex -kanji=utf8 $(LATEXOPTS) $$f; done - for f in *.idx; do mendex -U -f -d "`basename $$f .idx`.dic" -s python.ist $$f; done + -for f in *.idx; do mendex -U -f -d "`basename $$f .idx`.dic" -s python.ist $$f; done for f in *.tex; do platex -kanji=utf8 $(LATEXOPTS) $$f; done for f in *.tex; do platex -kanji=utf8 $(LATEXOPTS) $$f; done for f in *.dvi; do dvipdfmx $$f; done diff --git a/sphinx/texinputs/sphinx.sty b/sphinx/texinputs/sphinx.sty index a2b9bbb4c..ce15591a2 100644 --- a/sphinx/texinputs/sphinx.sty +++ b/sphinx/texinputs/sphinx.sty @@ -46,6 +46,13 @@ %\renewcommand{\paperwidth}{8.5in} % typical squarish manual %\renewcommand{\paperwidth}{7in} % O'Reilly ``Programmming Python'' +% use pdfoutput for pTeX and dvipdfmx +\ifx\kanjiskip\undefined\else + \ifx\Gin@driver{dvipdfmx.def}\undefined\else + \newcount\pdfoutput\pdfoutput=0 + \fi +\fi + % For graphicx, check if we are compiling under latex or pdflatex. \ifx\pdftexversion\undefined \usepackage{graphicx} @@ -112,6 +119,10 @@ \fancyhead[LE,RO]{{\py@HeaderFamily \@title, \py@release}} \renewcommand{\headrulewidth}{0.4pt} \renewcommand{\footrulewidth}{0.4pt} + % define chaptermark with \@chappos when \@chappos is available for Japanese + \ifx\@chappos\undefined\else + \def\chaptermark##1{\markboth{\@chapapp\space\thechapter\space\@chappos\space ##1}{}} + \fi } % Update the plain style so we get the page number & footer line, % but not a chapter or section title. This is to keep the first @@ -126,7 +137,7 @@ % Some custom font markup commands. % -\newcommand{\strong}[1]{{\bf #1}} +\newcommand{\strong}[1]{{\textbf{#1}}} \newcommand{\code}[1]{\texttt{#1}} \newcommand{\bfcode}[1]{\code{\bfseries#1}} \newcommand{\email}[1]{\textsf{#1}} @@ -322,7 +333,7 @@ \@ifundefined{ChTitleVar}{}{ \ChNameVar{\raggedleft\normalsize\py@HeaderFamily} \ChNumVar{\raggedleft \bfseries\Large\py@HeaderFamily} - \ChTitleVar{\raggedleft \rm\Huge\py@HeaderFamily} + \ChTitleVar{\raggedleft \textrm{\Huge\py@HeaderFamily}} % This creates chapter heads without the leading \vspace*{}: \def\@makechapterhead#1{% {\parindent \z@ \raggedright \normalfont @@ -423,6 +434,21 @@ } } +% to make pdf with correct encoded bookmarks in Japanese +% this should precede the hyperref package +\ifx\kanjiskip\undefined\else + \usepackage{atbegshi} + \ifx\ucs\undefined + \ifnum 42146=\euc"A4A2 + \AtBeginShipoutFirst{\special{pdf:tounicode EUC-UCS2}} + \else + \AtBeginShipoutFirst{\special{pdf:tounicode 90ms-RKSJ-UCS2}} + \fi + \else + \AtBeginShipoutFirst{\special{pdf:tounicode UTF8-UCS2}} + \fi +\fi + % Include hyperref last. \RequirePackage[colorlinks,breaklinks, linkcolor=InnerLinkColor,filecolor=OuterLinkColor, @@ -480,3 +506,37 @@ \@gobble } \def\FN@sf@gobble@twobracket[#1]#2{} + +% adjust the margins for footer, +% this works with the jsclasses only (Japanese standard document classes) +\ifx\@jsc@uplatextrue\undefined\else + \hypersetup{setpagesize=false} + \setlength\footskip{2\baselineskip} + \addtolength{\textheight}{-2\baselineskip} +\fi + +% fix the double index and bibliography on the table of contents +% in jsclasses (Japanese standard document classes) +\ifx\@jsc@uplatextrue\undefined\else + \renewcommand{\theindex}{ + \cleardoublepage + \phantomsection + \py@OldTheindex + } + \renewcommand{\thebibliography}[1]{ + \cleardoublepage + \phantomsection + \py@OldThebibliography{1} + } +\fi + +% do not use \@chappos in Appendix in pTeX +\ifx\kanjiskip\undefined\else + \renewcommand{\appendix}{\par + \setcounter{chapter}{0} + \setcounter{section}{0} + \gdef\@chapapp{\appendixname} + \gdef\@chappos{} + \gdef\thechapter{\@Alph\c@chapter} + } +\fi diff --git a/sphinx/texinputs/sphinxhowto.cls b/sphinx/texinputs/sphinxhowto.cls index f4e3d2f4e..9625870e7 100644 --- a/sphinx/texinputs/sphinxhowto.cls +++ b/sphinx/texinputs/sphinxhowto.cls @@ -1,5 +1,5 @@ % -% sphinxhowto.cls for Sphinx (http://sphinx.pocoo.org/) +% sphinxhowto.cls for Sphinx (http://sphinx-doc.org/) % \NeedsTeXFormat{LaTeX2e}[1995/12/01] diff --git a/sphinx/texinputs/sphinxmanual.cls b/sphinx/texinputs/sphinxmanual.cls index efb50381e..da76a77a1 100644 --- a/sphinx/texinputs/sphinxmanual.cls +++ b/sphinx/texinputs/sphinxmanual.cls @@ -1,5 +1,5 @@ % -% sphinxmanual.cls for Sphinx (http://sphinx.pocoo.org/) +% sphinxmanual.cls for Sphinx (http://sphinx-doc.org/) % \NeedsTeXFormat{LaTeX2e}[1995/12/01] diff --git a/sphinx/themes/agogo/layout.html b/sphinx/themes/agogo/layout.html index d063194a1..fde19dbc7 100644 --- a/sphinx/themes/agogo/layout.html +++ b/sphinx/themes/agogo/layout.html @@ -5,10 +5,10 @@ Sphinx layout template for the agogo theme, originally written by Andi Albrecht. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. #} -{% extends "basic/layout.html" %} +{%- extends "basic/layout.html" %} {% block header %}
        diff --git a/sphinx/themes/agogo/static/agogo.css_t b/sphinx/themes/agogo/static/agogo.css_t index b069bd224..3fb81178c 100644 --- a/sphinx/themes/agogo/static/agogo.css_t +++ b/sphinx/themes/agogo/static/agogo.css_t @@ -4,7 +4,7 @@ * * Sphinx stylesheet -- agogo theme. * - * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + * :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ diff --git a/sphinx/themes/agogo/theme.conf b/sphinx/themes/agogo/theme.conf index 3fc88580f..3052aca30 100644 --- a/sphinx/themes/agogo/theme.conf +++ b/sphinx/themes/agogo/theme.conf @@ -10,7 +10,7 @@ pagewidth = 70em documentwidth = 50em sidebarwidth = 20em bgcolor = #eeeeec -headerbg = url(bgtop.png) top left repeat-x +headerbg = #555573 url(bgtop.png) top left repeat-x footerbg = url(bgfooter.png) top left repeat-x linkcolor = #ce5c00 headercolor1 = #204a87 diff --git a/sphinx/themes/basic/defindex.html b/sphinx/themes/basic/defindex.html index ce8d3af67..1ae9630de 100644 --- a/sphinx/themes/basic/defindex.html +++ b/sphinx/themes/basic/defindex.html @@ -4,10 +4,10 @@ Default template for the "index" page. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. #} -{% extends "layout.html" %} +{%- extends "layout.html" %} {% set title = _('Overview') %} {% block body %}

        {{ docstitle|e }}

        diff --git a/sphinx/themes/basic/domainindex.html b/sphinx/themes/basic/domainindex.html index 947a01ea8..7f99da618 100644 --- a/sphinx/themes/basic/domainindex.html +++ b/sphinx/themes/basic/domainindex.html @@ -4,10 +4,10 @@ Template for domain indices (module index, ...). - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. #} -{% extends "layout.html" %} +{%- extends "layout.html" %} {% set title = indextitle %} {% block extrahead %} {{ super() }} diff --git a/sphinx/themes/basic/genindex-single.html b/sphinx/themes/basic/genindex-single.html index eff8c1ce2..e79212516 100644 --- a/sphinx/themes/basic/genindex-single.html +++ b/sphinx/themes/basic/genindex-single.html @@ -4,7 +4,7 @@ Template for a "single" page of a split index. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. #} {% macro indexentries(firstname, links) %} @@ -28,7 +28,7 @@ {% endmacro %} -{% extends "layout.html" %} +{%- extends "layout.html" %} {% set title = _('Index') %} {% block body %} diff --git a/sphinx/themes/basic/genindex-split.html b/sphinx/themes/basic/genindex-split.html index 6da88a173..20c180687 100644 --- a/sphinx/themes/basic/genindex-split.html +++ b/sphinx/themes/basic/genindex-split.html @@ -4,10 +4,10 @@ Template for a "split" index overview page. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. #} -{% extends "layout.html" %} +{%- extends "layout.html" %} {% set title = _('Index') %} {% block body %} diff --git a/sphinx/themes/basic/genindex.html b/sphinx/themes/basic/genindex.html index 7bc002b6c..dd2c96d8e 100644 --- a/sphinx/themes/basic/genindex.html +++ b/sphinx/themes/basic/genindex.html @@ -4,7 +4,7 @@ Template for an "all-in-one" index. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. #} {% macro indexentries(firstname, links) %} @@ -28,7 +28,7 @@ {% endmacro %} -{% extends "layout.html" %} +{%- extends "layout.html" %} {% set title = _('Index') %} {% block body %} diff --git a/sphinx/themes/basic/globaltoc.html b/sphinx/themes/basic/globaltoc.html index ee191faf1..6d117f299 100644 --- a/sphinx/themes/basic/globaltoc.html +++ b/sphinx/themes/basic/globaltoc.html @@ -4,7 +4,7 @@ Sphinx sidebar template: global table of contents. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. #}

        {{ _('Table Of Contents') }}

        diff --git a/sphinx/themes/basic/layout.html b/sphinx/themes/basic/layout.html index 9fb989cbe..9e4e39a18 100644 --- a/sphinx/themes/basic/layout.html +++ b/sphinx/themes/basic/layout.html @@ -4,7 +4,7 @@ Master layout template for Sphinx themes. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. #} {%- block doctype -%} @@ -195,7 +195,7 @@ {% trans last_updated=last_updated|e %}Last updated on {{ last_updated }}.{% endtrans %} {%- endif %} {%- if show_sphinx %} - {% trans sphinx_version=sphinx_version|e %}Created using Sphinx {{ sphinx_version }}.{% endtrans %} + {% trans sphinx_version=sphinx_version|e %}Created using Sphinx {{ sphinx_version }}.{% endtrans %} {%- endif %}
        {%- endblock %} diff --git a/sphinx/themes/basic/localtoc.html b/sphinx/themes/basic/localtoc.html index aa612ebf6..23a31256e 100644 --- a/sphinx/themes/basic/localtoc.html +++ b/sphinx/themes/basic/localtoc.html @@ -4,7 +4,7 @@ Sphinx sidebar template: local table of contents. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. #} {%- if display_toc %} diff --git a/sphinx/themes/basic/page.html b/sphinx/themes/basic/page.html index f6e7a688c..185c6c85a 100644 --- a/sphinx/themes/basic/page.html +++ b/sphinx/themes/basic/page.html @@ -4,10 +4,10 @@ Master template for simple pages. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. #} -{% extends "layout.html" %} +{%- extends "layout.html" %} {% block body %} {{ body }} {% endblock %} diff --git a/sphinx/themes/basic/relations.html b/sphinx/themes/basic/relations.html index 82abbeaa2..d7c5fa58e 100644 --- a/sphinx/themes/basic/relations.html +++ b/sphinx/themes/basic/relations.html @@ -4,7 +4,7 @@ Sphinx sidebar template: relation links. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. #} {%- if prev %} diff --git a/sphinx/themes/basic/search.html b/sphinx/themes/basic/search.html index 4cdc6935c..011c23929 100644 --- a/sphinx/themes/basic/search.html +++ b/sphinx/themes/basic/search.html @@ -4,10 +4,10 @@ Template for the search page. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. #} -{% extends "layout.html" %} +{%- extends "layout.html" %} {% set title = _('Search') %} {% set script_files = script_files + ['_static/searchtools.js'] %} {% block extrahead %} diff --git a/sphinx/themes/basic/searchbox.html b/sphinx/themes/basic/searchbox.html index 13b453c49..609aac83b 100644 --- a/sphinx/themes/basic/searchbox.html +++ b/sphinx/themes/basic/searchbox.html @@ -4,7 +4,7 @@ Sphinx sidebar template: quick search box. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. #} {%- if pagename != "search" %} diff --git a/sphinx/themes/basic/searchresults.html b/sphinx/themes/basic/searchresults.html index 667abffda..5c42fbaeb 100644 --- a/sphinx/themes/basic/searchresults.html +++ b/sphinx/themes/basic/searchresults.html @@ -4,7 +4,7 @@ Template for the body of the search results page. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. #}

        Search

        diff --git a/sphinx/themes/basic/sourcelink.html b/sphinx/themes/basic/sourcelink.html index 53f2f6b16..08232efce 100644 --- a/sphinx/themes/basic/sourcelink.html +++ b/sphinx/themes/basic/sourcelink.html @@ -4,7 +4,7 @@ Sphinx sidebar template: "show source" link. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. #} {%- if show_source and has_source and sourcename %} diff --git a/sphinx/themes/basic/static/basic.css_t b/sphinx/themes/basic/static/basic.css_t index 2937fa49b..b3e36db75 100644 --- a/sphinx/themes/basic/static/basic.css_t +++ b/sphinx/themes/basic/static/basic.css_t @@ -4,7 +4,7 @@ * * Sphinx stylesheet -- basic theme. * - * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + * :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ diff --git a/sphinx/themes/basic/static/doctools.js b/sphinx/themes/basic/static/doctools.js index d4619fdfb..8614442eb 100644 --- a/sphinx/themes/basic/static/doctools.js +++ b/sphinx/themes/basic/static/doctools.js @@ -4,7 +4,7 @@ * * Sphinx JavaScript utilities for all documentation. * - * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + * :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ @@ -32,7 +32,7 @@ if (!window.console || !console.firebug) { */ jQuery.urldecode = function(x) { return decodeURIComponent(x).replace(/\+/g, ' '); -} +}; /** * small helper function to urlencode strings @@ -61,18 +61,6 @@ jQuery.getQueryParameters = function(s) { return result; }; -/** - * small function to check if an array contains - * a given item. - */ -jQuery.contains = function(arr, item) { - for (var i = 0; i < arr.length; i++) { - if (arr[i] == item) - return true; - } - return false; -}; - /** * highlight a given string on a jquery object by wrapping it in * span elements with the given class name. diff --git a/sphinx/themes/basic/static/searchtools.js_t b/sphinx/themes/basic/static/searchtools.js_t index 45989c6ae..f96953b44 100644 --- a/sphinx/themes/basic/static/searchtools.js_t +++ b/sphinx/themes/basic/static/searchtools.js_t @@ -4,40 +4,47 @@ * * Sphinx JavaScript utilties for the full-text search. * - * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + * :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ -/** - * helper function to return a node containing the - * search summary for a given text. keywords is a list - * of stemmed words, hlwords is the list of normal, unstemmed - * words. the first one is used to find the occurance, the - * latter for highlighting it. - */ - -jQuery.makeSearchSummary = function(text, keywords, hlwords) { - var textLower = text.toLowerCase(); - var start = 0; - $.each(keywords, function() { - var i = textLower.indexOf(this.toLowerCase()); - if (i > -1) - start = i; - }); - start = Math.max(start - 120, 0); - var excerpt = ((start > 0) ? '...' : '') + - $.trim(text.substr(start, 240)) + - ((start + 240 - text.length) ? '...' : ''); - var rv = $('
        ').text(excerpt); - $.each(hlwords, function() { - rv = rv.highlightText(this, 'highlighted'); - }); - return rv; -} - {{ search_language_stemming_code|safe }} +{% if search_scorer_tool %} +{{ search_scorer_tool|safe }} +{% else %} +/** + * Simple result scoring code. + */ +var Scorer = { + // Implement the following function to further tweak the score for each result + // The function takes a result array [filename, title, anchor, descr, score] + // and returns the new score. + /* + score: function(result) { + return result[4]; + }, + */ + + // query matches the full name of an object + objNameMatch: 11, + // or matches in the last dotted part of the object name + objPartialMatch: 6, + // Additive scores depending on the priority of the object + objPrio: {0: 15, // used to be importantResults + 1: 5, // used to be objectResults + 2: -5}, // used to be unimportantResults + // Used when the priority is not in the mapping. + objPrioDefault: 0, + + // query found in title + title: 15, + // query found in terms + term: 5 +}; +{% endif %} + /** * Search Module */ @@ -86,19 +93,20 @@ var Search = { if (this._pulse_status >= 0) return; function pulse() { + var i; Search._pulse_status = (Search._pulse_status + 1) % 4; var dotString = ''; - for (var i = 0; i < Search._pulse_status; i++) + for (i = 0; i < Search._pulse_status; i++) dotString += '.'; Search.dots.text(dotString); if (Search._pulse_status > -1) window.setTimeout(pulse, 500); - }; + } pulse(); }, /** - * perform a search for something + * perform a search for something (or wait until index is loaded) */ performSearch : function(query) { // create the required interface elements @@ -118,41 +126,46 @@ var Search = { this.deferQuery(query); }, + /** + * execute search (requires search index to be loaded) + */ query : function(query) { + var i; var stopwords = {{ search_language_stop_words }}; - // Stem the searchterms and add them to the correct list + // stem the searchterms and add them to the correct list var stemmer = new Stemmer(); var searchterms = []; var excluded = []; var hlterms = []; var tmp = query.split(/\s+/); var objectterms = []; - for (var i = 0; i < tmp.length; i++) { - if (tmp[i] != "") { + for (i = 0; i < tmp.length; i++) { + if (tmp[i] !== "") { objectterms.push(tmp[i].toLowerCase()); } if ($u.indexOf(stopwords, tmp[i]) != -1 || tmp[i].match(/^\d+$/) || - tmp[i] == "") { + tmp[i] === "") { // skip this "word" continue; } // stem the word var word = stemmer.stemWord(tmp[i]).toLowerCase(); + var toAppend; // select the correct list if (word[0] == '-') { - var toAppend = excluded; + toAppend = excluded; word = word.substr(1); } else { - var toAppend = searchterms; + toAppend = searchterms; hlterms.push(tmp[i].toLowerCase()); } // only add if not already in the list - if (!$.contains(toAppend, word)) + if (!$u.contains(toAppend, word)) toAppend.push(word); - }; + } var highlightstring = '?highlight=' + $.urlencode(hlterms.join(" ")); // console.debug('SEARCH: searching for:'); @@ -160,89 +173,51 @@ var Search = { // console.info('excluded: ', excluded); // prepare search - var filenames = this._index.filenames; - var titles = this._index.titles; var terms = this._index.terms; - var fileMap = {}; - var files = null; - // different result priorities - var importantResults = []; - var objectResults = []; - var regularResults = []; - var unimportantResults = []; + var titleterms = this._index.titleterms; + + // array of [filename, title, anchor, descr, score] + var results = []; $('#search-progress').empty(); // lookup as object - for (var i = 0; i < objectterms.length; i++) { - var others = [].concat(objectterms.slice(0,i), - objectterms.slice(i+1, objectterms.length)) - var results = this.performObjectSearch(objectterms[i], others); - // Assume first word is most likely to be the object, - // other words more likely to be in description. - // Therefore put matches for earlier words first. - // (Results are eventually used in reverse order). - objectResults = results[0].concat(objectResults); - importantResults = results[1].concat(importantResults); - unimportantResults = results[2].concat(unimportantResults); + for (i = 0; i < objectterms.length; i++) { + var others = [].concat(objectterms.slice(0, i), + objectterms.slice(i+1, objectterms.length)); + results = results.concat(this.performObjectSearch(objectterms[i], others)); } - // perform the search on the required terms - for (var i = 0; i < searchterms.length; i++) { - var word = searchterms[i]; - // no match but word was a required one - if ((files = terms[word]) == null) - break; - if (files.length == undefined) { - files = [files]; - } - // create the mapping - for (var j = 0; j < files.length; j++) { - var file = files[j]; - if (file in fileMap) - fileMap[file].push(word); - else - fileMap[file] = [word]; - } + // lookup as search terms in fulltext + results = results.concat(this.performTermsSearch(searchterms, excluded, terms, Scorer.term)) + .concat(this.performTermsSearch(searchterms, excluded, titleterms, Scorer.title)); + + // let the scorer override scores with a custom scoring function + if (Scorer.score) { + for (i = 0; i < results.length; i++) + results[i][4] = Scorer.score(results[i]); } - // now check if the files don't contain excluded terms - for (var file in fileMap) { - var valid = true; - - // check if all requirements are matched - if (fileMap[file].length != searchterms.length) - continue; - - // ensure that none of the excluded terms is in the - // search result. - for (var i = 0; i < excluded.length; i++) { - if (terms[excluded[i]] == file || - $.contains(terms[excluded[i]] || [], file)) { - valid = false; - break; - } + // now sort the results by score (in opposite order of appearance, since the + // display function below uses pop() to retrieve items) and then + // alphabetically + results.sort(function(a, b) { + var left = a[4]; + var right = b[4]; + if (left > right) { + return 1; + } else if (left < right) { + return -1; + } else { + // same score: sort alphabetically + left = a[1].toLowerCase(); + right = b[1].toLowerCase(); + return (left > right) ? -1 : ((left < right) ? 1 : 0); } - - // if we have still a valid result we can add it - // to the result list - if (valid) - regularResults.push([filenames[file], titles[file], '', null]); - } - - // delete unused variables in order to not waste - // memory until list is retrieved completely - delete filenames, titles, terms; - - // now sort the regular results descending by title - regularResults.sort(function(a, b) { - var left = a[1].toLowerCase(); - var right = b[1].toLowerCase(); - return (left > right) ? -1 : ((left < right) ? 1 : 0); }); - // combine all results - var results = unimportantResults.concat(regularResults) - .concat(objectResults).concat(importantResults); + // for debugging + //Search.lastresults = results.slice(); // a copy + //console.info('search results:', Search.lastresults); // print the results var resultCount = results.length; @@ -251,7 +226,7 @@ var Search = { if (results.length) { var item = results.pop(); var listItem = $('
      • '); - if (DOCUMENTATION_OPTIONS.FILE_SUFFIX == '') { + if (DOCUMENTATION_OPTIONS.FILE_SUFFIX === '') { // dirhtml builder var dirname = item[0] + '/'; if (dirname.match(/\/index\/$/)) { @@ -277,8 +252,8 @@ var Search = { } else if (DOCUMENTATION_OPTIONS.HAS_SOURCE) { $.get(DOCUMENTATION_OPTIONS.URL_ROOT + '_sources/' + item[0] + '.txt', function(data) { - if (data != '') { - listItem.append($.makeSearchSummary(data, searchterms, hlterms)); + if (data !== '') { + listItem.append(Search.makeSearchSummary(data, searchterms, hlterms)); Search.output.append(listItem); } listItem.slideDown(5, function() { @@ -307,20 +282,32 @@ var Search = { displayNextItem(); }, + /** + * search for object names + */ performObjectSearch : function(object, otherterms) { var filenames = this._index.filenames; var objects = this._index.objects; var objnames = this._index.objnames; var titles = this._index.titles; - var importantResults = []; - var objectResults = []; - var unimportantResults = []; + var i; + var results = []; for (var prefix in objects) { for (var name in objects[prefix]) { var fullname = (prefix ? prefix + '.' : '') + name; if (fullname.toLowerCase().indexOf(object) > -1) { + var score = 0; + var parts = fullname.split('.'); + // check for different match types: exact matches of full name or + // "last name" (i.e. last dotted part) + if (fullname == object || parts[parts.length - 1] == object) { + score += Scorer.objNameMatch; + // matches in last name + } else if (parts[parts.length - 1].indexOf(object) > -1) { + score += Scorer.objPartialMatch; + } var match = objects[prefix][name]; var objname = objnames[match[1]][2]; var title = titles[match[0]]; @@ -330,7 +317,7 @@ var Search = { var haystack = (prefix + ' ' + name + ' ' + objname + ' ' + title).toLowerCase(); var allfound = true; - for (var i = 0; i < otherterms.length; i++) { + for (i = 0; i < otherterms.length; i++) { if (haystack.indexOf(otherterms[i]) == -1) { allfound = false; break; @@ -341,37 +328,107 @@ var Search = { } } var descr = objname + _(', in ') + title; - anchor = match[3]; - if (anchor == '') + + var anchor = match[3]; + if (anchor === '') anchor = fullname; else if (anchor == '-') anchor = objnames[match[1]][1] + '-' + fullname; - result = [filenames[match[0]], fullname, '#'+anchor, descr]; - switch (match[2]) { - case 1: objectResults.push(result); break; - case 0: importantResults.push(result); break; - case 2: unimportantResults.push(result); break; + // add custom score for some objects according to scorer + if (Scorer.objPrio.hasOwnProperty(match[2])) { + score += Scorer.objPrio[match[2]]; + } else { + score += Scorer.objPrioDefault; } + results.push([filenames[match[0]], fullname, '#'+anchor, descr, score]); } } } - // sort results descending - objectResults.sort(function(a, b) { - return (a[1] > b[1]) ? -1 : ((a[1] < b[1]) ? 1 : 0); - }); + return results; + }, - importantResults.sort(function(a, b) { - return (a[1] > b[1]) ? -1 : ((a[1] < b[1]) ? 1 : 0); - }); + /** + * search for full-text terms in the index + */ + performTermsSearch : function(searchterms, excluded, terms, score) { + var filenames = this._index.filenames; + var titles = this._index.titles; - unimportantResults.sort(function(a, b) { - return (a[1] > b[1]) ? -1 : ((a[1] < b[1]) ? 1 : 0); - }); + var i, j, file, files; + var fileMap = {}; + var results = []; - return [importantResults, objectResults, unimportantResults] + // perform the search on the required terms + for (i = 0; i < searchterms.length; i++) { + var word = searchterms[i]; + // no match but word was a required one + if (!(files = terms[word])) + break; + if (files.length === undefined) { + files = [files]; + } + // create the mapping + for (j = 0; j < files.length; j++) { + file = files[j]; + if (file in fileMap) + fileMap[file].push(word); + else + fileMap[file] = [word]; + } + } + + // now check if the files don't contain excluded terms + for (file in fileMap) { + var valid = true; + + // check if all requirements are matched + if (fileMap[file].length != searchterms.length) + continue; + + // ensure that none of the excluded terms is in the search result + for (i = 0; i < excluded.length; i++) { + if (terms[excluded[i]] == file || + $u.contains(terms[excluded[i]] || [], file)) { + valid = false; + break; + } + } + + // if we have still a valid result we can add it to the result list + if (valid) { + results.push([filenames[file], titles[file], '', null, score]); + } + } + return results; + }, + + /** + * helper function to return a node containing the + * search summary for a given text. keywords is a list + * of stemmed words, hlwords is the list of normal, unstemmed + * words. the first one is used to find the occurance, the + * latter for highlighting it. + */ + makeSearchSummary : function(text, keywords, hlwords) { + var textLower = text.toLowerCase(); + var start = 0; + $.each(keywords, function() { + var i = textLower.indexOf(this.toLowerCase()); + if (i > -1) + start = i; + }); + start = Math.max(start - 120, 0); + var excerpt = ((start > 0) ? '...' : '') + + $.trim(text.substr(start, 240)) + + ((start + 240 - text.length) ? '...' : ''); + var rv = $('
        ').text(excerpt); + $.each(hlwords, function() { + rv = rv.highlightText(this, 'highlighted'); + }); + return rv; } -} +}; $(document).ready(function() { Search.init(); diff --git a/sphinx/themes/basic/static/websupport.js b/sphinx/themes/basic/static/websupport.js index e9bd1b851..19fcda564 100644 --- a/sphinx/themes/basic/static/websupport.js +++ b/sphinx/themes/basic/static/websupport.js @@ -4,7 +4,7 @@ * * sphinx.websupport utilties for all documentation. * - * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + * :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ diff --git a/sphinx/themes/default/layout.html b/sphinx/themes/default/layout.html index d91a56555..d237f5ed9 100644 --- a/sphinx/themes/default/layout.html +++ b/sphinx/themes/default/layout.html @@ -4,10 +4,10 @@ Sphinx layout template for the default theme. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. #} -{% extends "basic/layout.html" %} +{%- extends "basic/layout.html" %} {% if theme_collapsiblesidebar|tobool %} {% set script_files = script_files + ['_static/sidebar.js'] %} diff --git a/sphinx/themes/default/static/default.css_t b/sphinx/themes/default/static/default.css_t index 85c9436a9..5db771089 100644 --- a/sphinx/themes/default/static/default.css_t +++ b/sphinx/themes/default/static/default.css_t @@ -4,7 +4,7 @@ * * Sphinx stylesheet -- default theme. * - * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + * :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ diff --git a/sphinx/themes/default/static/sidebar.js b/sphinx/themes/default/static/sidebar.js_t similarity index 79% rename from sphinx/themes/default/static/sidebar.js rename to sphinx/themes/default/static/sidebar.js_t index a45e1926a..242005254 100644 --- a/sphinx/themes/default/static/sidebar.js +++ b/sphinx/themes/default/static/sidebar.js_t @@ -16,12 +16,26 @@ * Once the browser is closed the cookie is deleted and the position * reset to the default (expanded). * - * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + * :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ $(function() { + {% if theme_rightsidebar|tobool %} + {% set side = 'right' %} + {% set opposite = 'left' %} + {% set initial_label = '»' %} + {% set expand_label = '«' %} + {% set collapse_label = '»' %} + {% else %} + {% set side = 'left' %} + {% set opposite = 'right' %} + {% set initial_label = '«' %} + {% set expand_label = '»' %} + {% set collapse_label = '«' %} + {% endif %} + // global elements used by the functions. // the 'sidebarbutton' element is defined as global after its // creation, in the add_sidebar_button function @@ -34,7 +48,7 @@ $(function() { // original margin-left of the bodywrapper and width of the sidebar // with the sidebar expanded - var bw_margin_expanded = bodywrapper.css('margin-left'); + var bw_margin_expanded = bodywrapper.css('margin-{{side}}'); var ssb_width_expanded = sidebar.width(); // margin-left of the bodywrapper and width of the sidebar @@ -60,38 +74,38 @@ $(function() { function collapse_sidebar() { sidebarwrapper.hide(); sidebar.css('width', ssb_width_collapsed); - bodywrapper.css('margin-left', bw_margin_collapsed); + bodywrapper.css('margin-{{side}}', bw_margin_collapsed); sidebarbutton.css({ - 'margin-left': '0', + 'margin-{{side}}': '0', 'height': bodywrapper.height() }); - sidebarbutton.find('span').text('»'); + sidebarbutton.find('span').text('{{expand_label}}'); sidebarbutton.attr('title', _('Expand sidebar')); document.cookie = 'sidebar=collapsed'; } function expand_sidebar() { - bodywrapper.css('margin-left', bw_margin_expanded); + bodywrapper.css('margin-{{side}}', bw_margin_expanded); sidebar.css('width', ssb_width_expanded); sidebarwrapper.show(); sidebarbutton.css({ - 'margin-left': ssb_width_expanded-12, + 'margin-{{side}}': ssb_width_expanded-12, 'height': bodywrapper.height() }); - sidebarbutton.find('span').text('«'); + sidebarbutton.find('span').text('{{collapse_label}}'); sidebarbutton.attr('title', _('Collapse sidebar')); document.cookie = 'sidebar=expanded'; } function add_sidebar_button() { sidebarwrapper.css({ - 'float': 'left', - 'margin-right': '0', + 'float': '{{side}}', + 'margin-{{opposite}}': '0', 'width': ssb_width_expanded - 28 }); // create the button sidebar.append( - '
        «
        ' + '
        {{initial_label}}
        ' ); var sidebarbutton = $('#sidebarbutton'); light_color = sidebarbutton.css('background-color'); @@ -110,12 +124,12 @@ $(function() { sidebarbutton.attr('title', _('Collapse sidebar')); sidebarbutton.css({ 'color': '#FFFFFF', - 'border-left': '1px solid ' + dark_color, + 'border-{{side}}': '1px solid ' + dark_color, 'font-size': '1.2em', 'cursor': 'pointer', 'height': bodywrapper.height(), 'padding-top': '1px', - 'margin-left': ssb_width_expanded - 12 + 'margin-{{side}}': ssb_width_expanded - 12 }); sidebarbutton.hover( diff --git a/sphinx/themes/epub/epub-cover.html b/sphinx/themes/epub/epub-cover.html index b3202a33f..5872fb7f1 100644 --- a/sphinx/themes/epub/epub-cover.html +++ b/sphinx/themes/epub/epub-cover.html @@ -4,10 +4,10 @@ Sample template for the html cover page. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. #} -{% extends "layout.html" %} +{%- extends "layout.html" %} {%- block header %}{% endblock %} {%- block rootrellink %}{% endblock %} {%- block relbaritems %}{% endblock %} diff --git a/sphinx/themes/epub/layout.html b/sphinx/themes/epub/layout.html index 1f5ad077f..c2e2e0fd5 100644 --- a/sphinx/themes/epub/layout.html +++ b/sphinx/themes/epub/layout.html @@ -4,10 +4,10 @@ Sphinx layout template for the epub theme. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. #} -{% extends "basic/layout.html" %} +{%- extends "basic/layout.html" %} {# add only basic navigation links #} {% block sidebar1 %}{% endblock %} diff --git a/sphinx/themes/epub/static/epub.css b/sphinx/themes/epub/static/epub.css index d2c51751a..9ce90fae2 100644 --- a/sphinx/themes/epub/static/epub.css +++ b/sphinx/themes/epub/static/epub.css @@ -4,7 +4,7 @@ * * Sphinx stylesheet -- epub theme. * - * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + * :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ diff --git a/sphinx/themes/haiku/layout.html b/sphinx/themes/haiku/layout.html index 719dba770..edbda50b2 100644 --- a/sphinx/themes/haiku/layout.html +++ b/sphinx/themes/haiku/layout.html @@ -4,10 +4,10 @@ Sphinx layout template for the haiku theme. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. #} -{% extends "basic/layout.html" %} +{%- extends "basic/layout.html" %} {% set script_files = script_files + ['_static/theme_extras.js'] %} {% set css_files = css_files + ['_static/print.css'] %} diff --git a/sphinx/themes/haiku/static/haiku.css_t b/sphinx/themes/haiku/static/haiku.css_t index 19f4e0bfd..87b116aeb 100644 --- a/sphinx/themes/haiku/static/haiku.css_t +++ b/sphinx/themes/haiku/static/haiku.css_t @@ -16,7 +16,7 @@ * Braden Ewing * Humdinger * - * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + * :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ diff --git a/sphinx/themes/nature/static/nature.css_t b/sphinx/themes/nature/static/nature.css_t index a98bd4209..3c4920341 100644 --- a/sphinx/themes/nature/static/nature.css_t +++ b/sphinx/themes/nature/static/nature.css_t @@ -4,7 +4,7 @@ * * Sphinx stylesheet -- nature theme. * - * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + * :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ diff --git a/sphinx/themes/pyramid/layout.html b/sphinx/themes/pyramid/layout.html index 1887361ee..8780ceaef 100644 --- a/sphinx/themes/pyramid/layout.html +++ b/sphinx/themes/pyramid/layout.html @@ -1,4 +1,4 @@ -{% extends "basic/layout.html" %} +{%- extends "basic/layout.html" %} {%- block extrahead %} diff --git a/sphinx/themes/scrolls/layout.html b/sphinx/themes/scrolls/layout.html index 92cb694db..97f7ca1db 100644 --- a/sphinx/themes/scrolls/layout.html +++ b/sphinx/themes/scrolls/layout.html @@ -5,10 +5,10 @@ Sphinx layout template for the scrolls theme, originally written by Armin Ronacher. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. #} -{% extends "basic/layout.html" %} +{%- extends "basic/layout.html" %} {% set script_files = script_files + ['_static/theme_extras.js'] %} {% set css_files = css_files + ['_static/print.css'] %} {# do not display relbars #} diff --git a/sphinx/themes/scrolls/static/scrolls.css_t b/sphinx/themes/scrolls/static/scrolls.css_t index e3d26ea39..c335f167e 100644 --- a/sphinx/themes/scrolls/static/scrolls.css_t +++ b/sphinx/themes/scrolls/static/scrolls.css_t @@ -4,7 +4,7 @@ * * Sphinx stylesheet -- scrolls theme. * - * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + * :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ diff --git a/sphinx/themes/sphinxdoc/layout.html b/sphinx/themes/sphinxdoc/layout.html index c93191851..4ffeb6ed2 100644 --- a/sphinx/themes/sphinxdoc/layout.html +++ b/sphinx/themes/sphinxdoc/layout.html @@ -4,10 +4,10 @@ Sphinx layout template for the sphinxdoc theme. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. #} -{% extends "basic/layout.html" %} +{%- extends "basic/layout.html" %} {# put the sidebar before the body #} {% block sidebar1 %}{{ sidebar() }}{% endblock %} diff --git a/sphinx/themes/sphinxdoc/static/sphinxdoc.css_t b/sphinx/themes/sphinxdoc/static/sphinxdoc.css_t index f535696b2..af4982577 100644 --- a/sphinx/themes/sphinxdoc/static/sphinxdoc.css_t +++ b/sphinx/themes/sphinxdoc/static/sphinxdoc.css_t @@ -5,7 +5,7 @@ * Sphinx stylesheet -- sphinxdoc theme. Originally created by * Armin Ronacher for Werkzeug. * - * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + * :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ diff --git a/sphinx/themes/traditional/static/traditional.css_t b/sphinx/themes/traditional/static/traditional.css_t index 51567255b..6c6bd5f5a 100644 --- a/sphinx/themes/traditional/static/traditional.css_t +++ b/sphinx/themes/traditional/static/traditional.css_t @@ -4,7 +4,7 @@ * * Sphinx stylesheet -- traditional docs.python.org theme. * - * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + * :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ diff --git a/sphinx/theming.py b/sphinx/theming.py index 68d11a490..dd20aa2b3 100644 --- a/sphinx/theming.py +++ b/sphinx/theming.py @@ -5,7 +5,7 @@ Theming support for HTML builders. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/transforms.py b/sphinx/transforms.py new file mode 100644 index 000000000..5b96300de --- /dev/null +++ b/sphinx/transforms.py @@ -0,0 +1,319 @@ +# -*- coding: utf-8 -*- +""" + sphinx.transforms + ~~~~~~~~~~~~~~~~~ + + Docutils transforms used by Sphinx when reading documents. + + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" + +from os import path + +from docutils import nodes +from docutils.utils import new_document, relative_path +from docutils.parsers.rst import Parser as RSTParser +from docutils.transforms import Transform +from docutils.transforms.parts import ContentsFilter + +from sphinx import addnodes +from sphinx.locale import _, init as init_locale +from sphinx.util import split_index_msg +from sphinx.util.nodes import traverse_translatable_index, extract_messages +from sphinx.util.osutil import ustrftime, find_catalog +from sphinx.util.pycompat import all + + +default_substitutions = set([ + 'version', + 'release', + 'today', +]) + +class DefaultSubstitutions(Transform): + """ + Replace some substitutions if they aren't defined in the document. + """ + # run before the default Substitutions + default_priority = 210 + + def apply(self): + config = self.document.settings.env.config + # only handle those not otherwise defined in the document + to_handle = default_substitutions - set(self.document.substitution_defs) + for ref in self.document.traverse(nodes.substitution_reference): + refname = ref['refname'] + if refname in to_handle: + text = config[refname] + if refname == 'today' and not text: + # special handling: can also specify a strftime format + text = ustrftime(config.today_fmt or _('%B %d, %Y')) + ref.replace_self(nodes.Text(text, text)) + + +class MoveModuleTargets(Transform): + """ + Move module targets that are the first thing in a section to the section + title. + + XXX Python specific + """ + default_priority = 210 + + def apply(self): + for node in self.document.traverse(nodes.target): + if not node['ids']: + continue + if (node.has_key('ismod') and + node.parent.__class__ is nodes.section and + # index 0 is the section title node + node.parent.index(node) == 1): + node.parent['ids'][0:0] = node['ids'] + node.parent.remove(node) + + +class HandleCodeBlocks(Transform): + """ + Several code block related transformations. + """ + default_priority = 210 + + def apply(self): + # move doctest blocks out of blockquotes + for node in self.document.traverse(nodes.block_quote): + if all(isinstance(child, nodes.doctest_block) for child + in node.children): + node.replace_self(node.children) + # combine successive doctest blocks + #for node in self.document.traverse(nodes.doctest_block): + # if node not in node.parent.children: + # continue + # parindex = node.parent.index(node) + # while len(node.parent) > parindex+1 and \ + # isinstance(node.parent[parindex+1], nodes.doctest_block): + # node[0] = nodes.Text(node[0] + '\n\n' + + # node.parent[parindex+1][0]) + # del node.parent[parindex+1] + + +class SortIds(Transform): + """ + Sort secion IDs so that the "id[0-9]+" one comes last. + """ + default_priority = 261 + + def apply(self): + for node in self.document.traverse(nodes.section): + if len(node['ids']) > 1 and node['ids'][0].startswith('id'): + node['ids'] = node['ids'][1:] + [node['ids'][0]] + + +class CitationReferences(Transform): + """ + Replace citation references by pending_xref nodes before the default + docutils transform tries to resolve them. + """ + default_priority = 619 + + def apply(self): + for citnode in self.document.traverse(nodes.citation_reference): + cittext = citnode.astext() + refnode = addnodes.pending_xref(cittext, reftype='citation', + reftarget=cittext, refwarn=True, + ids=citnode["ids"]) + refnode.line = citnode.line or citnode.parent.line + refnode += nodes.Text('[' + cittext + ']') + citnode.parent.replace(citnode, refnode) + + +class CustomLocaleReporter(object): + """ + Replacer for document.reporter.get_source_and_line method. + + reST text lines for translation not have original source line number. + This class provide correct line number at reporting. + """ + def __init__(self, source, line): + self.source, self.line = source, line + + try: + from docutils import __version__ as du_version + v = tuple([int(x) for x in du_version.split('.')[:2]]) + except ImportError: + v = (99, 99) + self.du_version = v + + def set_reporter(self, document): + if self.du_version < (0, 9): + document.reporter.locator = self.get_source_and_line + else: + document.reporter.get_source_and_line = self.get_source_and_line + + def get_source_and_line(self, lineno=None): + return self.source, self.line + + +class Locale(Transform): + """ + Replace translatable nodes with their translated doctree. + """ + default_priority = 0 + + def apply(self): + env = self.document.settings.env + settings, source = self.document.settings, self.document['source'] + # XXX check if this is reliable + assert source.startswith(env.srcdir) + docname = path.splitext(relative_path(env.srcdir, source))[0] + textdomain = find_catalog(docname, + self.document.settings.gettext_compact) + + # fetch translations + dirs = [path.join(env.srcdir, directory) + for directory in env.config.locale_dirs] + catalog, has_catalog = init_locale(dirs, env.config.language, + textdomain) + if not has_catalog: + return + + parser = RSTParser() + + for node, msg in extract_messages(self.document): + msgstr = catalog.gettext(msg) + # XXX add marker to untranslated parts + if not msgstr or msgstr == msg: # as-of-yet untranslated + continue + + # Avoid "Literal block expected; none found." warnings. + # If msgstr ends with '::' then it cause warning message at + # parser.parse() processing. + # literal-block-warning is only appear in avobe case. + if msgstr.strip().endswith('::'): + msgstr += '\n\n dummy literal' + # dummy literal node will discard by 'patch = patch[0]' + + patch = new_document(source, settings) + CustomLocaleReporter(node.source, node.line).set_reporter(patch) + parser.parse(msgstr, patch) + patch = patch[0] + # XXX doctest and other block markup + if not isinstance(patch, nodes.paragraph): + continue # skip for now + + # auto-numbered foot note reference should use original 'ids'. + def is_autonumber_footnote_ref(node): + return isinstance(node, nodes.footnote_reference) and \ + node.get('auto') == 1 + old_foot_refs = node.traverse(is_autonumber_footnote_ref) + new_foot_refs = patch.traverse(is_autonumber_footnote_ref) + if len(old_foot_refs) != len(new_foot_refs): + env.warn_node('inconsistent footnote references in ' + 'translated message', node) + for old, new in zip(old_foot_refs, new_foot_refs): + new['ids'] = old['ids'] + for id in new['ids']: + self.document.ids[id] = new + self.document.autofootnote_refs.remove(old) + self.document.note_autofootnote_ref(new) + + # reference should use original 'refname'. + # * reference target ".. _Python: ..." is not translatable. + # * section refname is not translatable. + # * inline reference "`Python <...>`_" has no 'refname'. + def is_refnamed_ref(node): + return isinstance(node, nodes.reference) and \ + 'refname' in node + old_refs = node.traverse(is_refnamed_ref) + new_refs = patch.traverse(is_refnamed_ref) + applied_refname_map = {} + if len(old_refs) != len(new_refs): + env.warn_node('inconsistent references in ' + 'translated message', node) + for new in new_refs: + if new['refname'] in applied_refname_map: + # 2nd appearance of the reference + new['refname'] = applied_refname_map[new['refname']] + elif old_refs: + # 1st appearance of the reference in old_refs + old = old_refs.pop(0) + refname = old['refname'] + new['refname'] = refname + applied_refname_map[new['refname']] = refname + else: + # the reference is not found in old_refs + applied_refname_map[new['refname']] = new['refname'] + + self.document.note_refname(new) + + # refnamed footnote and citation should use original 'ids'. + def is_refnamed_footnote_ref(node): + footnote_ref_classes = (nodes.footnote_reference, + nodes.citation_reference) + return isinstance(node, footnote_ref_classes) and \ + 'refname' in node + old_refs = node.traverse(is_refnamed_footnote_ref) + new_refs = patch.traverse(is_refnamed_footnote_ref) + refname_ids_map = {} + if len(old_refs) != len(new_refs): + env.warn_node('inconsistent references in ' + 'translated message', node) + for old in old_refs: + refname_ids_map[old["refname"]] = old["ids"] + for new in new_refs: + refname = new["refname"] + if refname in refname_ids_map: + new["ids"] = refname_ids_map[refname] + + # Original pending_xref['reftarget'] contain not-translated + # target name, new pending_xref must use original one. + # This code restricts to change ref-targets in the translation. + old_refs = node.traverse(addnodes.pending_xref) + new_refs = patch.traverse(addnodes.pending_xref) + xref_reftarget_map = {} + if len(old_refs) != len(new_refs): + env.warn_node('inconsistent term references in ' + 'translated message', node) + for old in old_refs: + key = old["reftype"], old["refdomain"] + xref_reftarget_map[key] = old["reftarget"] + for new in new_refs: + key = new["reftype"], new["refdomain"] + if key in xref_reftarget_map: + new['reftarget'] = xref_reftarget_map[key] + + # update leaves + for child in patch.children: + child.parent = node + node.children = patch.children + + # Extract and translate messages for index entries. + for node, entries in traverse_translatable_index(self.document): + new_entries = [] + for type, msg, tid, main in entries: + msg_parts = split_index_msg(type, msg) + msgstr_parts = [] + for part in msg_parts: + msgstr = catalog.gettext(part) + if not msgstr: + msgstr = part + msgstr_parts.append(msgstr) + + new_entries.append((type, ';'.join(msgstr_parts), tid, main)) + + node['raw_entries'] = entries + node['entries'] = new_entries + + +class SphinxContentsFilter(ContentsFilter): + """ + Used with BuildEnvironment.add_toc_from() to discard cross-file links + within table-of-contents link nodes. + """ + def visit_pending_xref(self, node): + text = node.astext() + self.parent.append(nodes.literal(text, text)) + raise nodes.SkipNode + + def visit_image(self, node): + raise nodes.SkipNode diff --git a/sphinx/util/__init__.py b/sphinx/util/__init__.py index 6cb83aec2..8bedda126 100644 --- a/sphinx/util/__init__.py +++ b/sphinx/util/__init__.py @@ -5,7 +5,7 @@ Utility functions for Sphinx. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ @@ -197,13 +197,18 @@ def get_module_source(modname): except Exception, err: raise PycodeError('error importing %r' % modname, err) mod = sys.modules[modname] - if hasattr(mod, '__loader__'): + filename = getattr(mod, '__file__', None) + loader = getattr(mod, '__loader__', None) + if loader and getattr(loader, 'get_filename', None): try: - source = mod.__loader__.get_source(modname) + filename = loader.get_filename(modname) + except Exception, err: + raise PycodeError('error getting filename for %r' % filename, err) + if filename is None and loader: + try: + return 'string', loader.get_source(modname) except Exception, err: raise PycodeError('error getting source for %r' % modname, err) - return 'string', source - filename = getattr(mod, '__file__', None) if filename is None: raise PycodeError('no source found for module %r' % modname) filename = path.normpath(path.abspath(filename)) @@ -286,6 +291,12 @@ class Tee(object): self.stream1.write(text) self.stream2.write(text) + def flush(self): + if hasattr(self.stream1, 'flush'): + self.stream1.flush() + if hasattr(self.stream2, 'flush'): + self.stream2.flush() + def parselinenos(spec, total): """Parse a line number spec (such as "1,2,4-6") and return a list of @@ -349,6 +360,29 @@ def split_into(n, type, value): return parts +def split_index_msg(type, value): + # new entry types must be listed in directives/other.py! + result = [] + try: + if type == 'single': + try: + result = split_into(2, 'single', value) + except ValueError: + result = split_into(1, 'single', value) + elif type == 'pair': + result = split_into(2, 'pair', value) + elif type == 'triple': + result = split_into(3, 'triple', value) + elif type == 'see': + result = split_into(2, 'see', value) + elif type == 'seealso': + result = split_into(2, 'see', value) + except ValueError: + pass + + return result + + def format_exception_cut_frames(x=1): """Format an exception with traceback, but only the last x frames.""" typ, val, tb = sys.exc_info() diff --git a/sphinx/util/compat.py b/sphinx/util/compat.py index bdb00845a..916f6fa3b 100644 --- a/sphinx/util/compat.py +++ b/sphinx/util/compat.py @@ -5,7 +5,7 @@ Stuff for docutils compatibility. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/util/console.py b/sphinx/util/console.py index ac85034d9..b3b27a489 100644 --- a/sphinx/util/console.py +++ b/sphinx/util/console.py @@ -5,7 +5,7 @@ Format colored console output. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/util/docfields.py b/sphinx/util/docfields.py index 896319f56..961b09a78 100644 --- a/sphinx/util/docfields.py +++ b/sphinx/util/docfields.py @@ -6,7 +6,7 @@ "Doc fields" are reST field lists in object descriptions that will be domain-specifically transformed to a more appealing presentation. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/util/docstrings.py b/sphinx/util/docstrings.py index ba81bf00e..d45b938d2 100644 --- a/sphinx/util/docstrings.py +++ b/sphinx/util/docstrings.py @@ -5,7 +5,7 @@ Utilities for docstring processing. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/util/inspect.py b/sphinx/util/inspect.py index b5c3db598..95b7cb1ee 100644 --- a/sphinx/util/inspect.py +++ b/sphinx/util/inspect.py @@ -5,7 +5,7 @@ Helpers for inspecting Python modules. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ @@ -27,13 +27,18 @@ if sys.version_info >= (2, 5): func = func.im_func parts = 0, () if type(func) is partial: - parts = len(func.args), func.keywords.keys() + keywords = func.keywords + if keywords is None: + keywords = {} + parts = len(func.args), keywords.keys() func = func.func if not inspect.isfunction(func): raise TypeError('%r is not a Python function' % func) args, varargs, varkw = inspect.getargs(func.func_code) func_defaults = func.func_defaults - if func_defaults: + if func_defaults is None: + func_defaults = [] + else: func_defaults = list(func_defaults) if parts[0]: args = args[parts[0]:] @@ -45,7 +50,10 @@ if sys.version_info >= (2, 5): del func_defaults[i] except IndexError: pass - return inspect.ArgSpec(args, varargs, varkw, func_defaults) + if sys.version_info >= (2, 6): + return inspect.ArgSpec(args, varargs, varkw, func_defaults) + else: + return (args, varargs, varkw, func_defaults) else: getargspec = inspect.getargspec @@ -70,12 +78,12 @@ def safe_getattr(obj, name, *defargs): raise AttributeError(name) -def safe_getmembers(object, predicate=None): +def safe_getmembers(object, predicate=None, attr_getter=safe_getattr): """A version of inspect.getmembers() that uses safe_getattr().""" results = [] for key in dir(object): try: - value = safe_getattr(object, key, None) + value = attr_getter(object, key, None) except AttributeError: continue if not predicate or predicate(value): diff --git a/sphinx/util/jsdump.py b/sphinx/util/jsdump.py index 191e24191..51fe73380 100644 --- a/sphinx/util/jsdump.py +++ b/sphinx/util/jsdump.py @@ -6,7 +6,7 @@ This module implements a simple JavaScript serializer. Uses the basestring encode function from simplejson by Bob Ippolito. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/util/jsonimpl.py b/sphinx/util/jsonimpl.py index cf5ddb424..aa0ea8251 100644 --- a/sphinx/util/jsonimpl.py +++ b/sphinx/util/jsonimpl.py @@ -5,7 +5,7 @@ JSON serializer implementation wrapper. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/util/matching.py b/sphinx/util/matching.py index fa6cb7e0b..b4c710765 100644 --- a/sphinx/util/matching.py +++ b/sphinx/util/matching.py @@ -5,7 +5,7 @@ Pattern-matching utility functions for Sphinx. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/util/nodes.py b/sphinx/util/nodes.py index dbedb7f2f..1d4d3ba53 100644 --- a/sphinx/util/nodes.py +++ b/sphinx/util/nodes.py @@ -5,7 +5,7 @@ Docutils node-related utility functions for Sphinx. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ @@ -43,6 +43,22 @@ IGNORED_NODES = ( def extract_messages(doctree): """Extract translatable messages from a document tree.""" for node in doctree.traverse(nodes.TextElement): + # workaround: nodes.term doesn't have source, line and rawsource + # (fixed in Docutils r7495) + if isinstance(node, nodes.term) and not node.source: + definition_list_item = node.parent + if definition_list_item.line is not None: + node.source = definition_list_item.source + node.line = definition_list_item.line - 1 + node.rawsource = definition_list_item.\ + rawsource.split("\n", 2)[0] + # workaround: nodes.caption doesn't have source, line. + # this issue was filed to Docutils tracker: + # sf.net/tracker/?func=detail&aid=3599485&group_id=38414&atid=422032 + if isinstance(node, nodes.caption) and not node.source: + node.source = node.parent.source + node.line = 0 #need fix docutils to get `node.line` + if not node.source: continue # built-in message if isinstance(node, IGNORED_NODES): @@ -58,6 +74,19 @@ def extract_messages(doctree): yield node, msg +def traverse_translatable_index(doctree): + """Traverse translatable index node from a document tree.""" + def is_block_index(node): + return isinstance(node, addnodes.index) and \ + node.get('inline') == False + for node in doctree.traverse(is_block_index): + if 'raw_entries' in node: + entries = node['raw_entries'] + else: + entries = node['entries'] + yield node, entries + + def nested_parse_with_titles(state, content, node): """Version of state.nested_parse() that allows titles and does not require titles to have the same decoration as the calling document. @@ -204,3 +233,17 @@ def _new_copy(self): return self.__class__(self.rawsource, **self.attributes) nodes.Element.copy = _new_copy + +# monkey-patch Element.__repr__ to return str if include unicode. +# sf.net/tracker/?func=detail&aid=3601607&group_id=38414&atid=422030 +import sys +if sys.version_info < (3,): + _element_repr_orig = nodes.Element.__repr__ + + def _repr(self): + s = _element_repr_orig(self) + if isinstance(s, unicode): + return s.encode('utf-8') + return s + + nodes.Element.__repr__ = _repr diff --git a/sphinx/util/osutil.py b/sphinx/util/osutil.py index 5becc37df..7322289ef 100644 --- a/sphinx/util/osutil.py +++ b/sphinx/util/osutil.py @@ -5,7 +5,7 @@ Operating system-related utility functions for Sphinx. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ @@ -40,12 +40,20 @@ def relative_uri(base, to): return to b2 = base.split(SEP) t2 = to.split(SEP) - # remove common segments - for x, y in zip(b2, t2): + # remove common segments (except the last segment) + for x, y in zip(b2[:-1], t2[:-1]): if x != y: break b2.pop(0) t2.pop(0) + if b2 == t2: + # Special case: relative_uri('f/index.html','f/index.html') + # returns '', not 'index.html' + return '' + if len(b2) == 1 and t2 == ['']: + # Special case: relative_uri('f/index.html','f/') should + # return './', not '' + return '.' + SEP return ('..' + SEP) * (len(b2)-1) + SEP.join(t2) @@ -136,8 +144,9 @@ else: def safe_relpath(path, start=None): + from sphinx.util.pycompat import relpath try: - return os.path.relpath(path, start) + return relpath(path, start) except ValueError: return path @@ -148,3 +157,6 @@ def find_catalog(docname, compaction): ret = docname return ret + +fs_encoding = sys.getfilesystemencoding() or sys.getdefaultencoding() + diff --git a/sphinx/util/png.py b/sphinx/util/png.py index 50c72efdc..3adabadf9 100644 --- a/sphinx/util/png.py +++ b/sphinx/util/png.py @@ -5,7 +5,7 @@ PNG image manipulation helpers. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/util/pycompat.py b/sphinx/util/pycompat.py index 9e081b02f..3d252c917 100644 --- a/sphinx/util/pycompat.py +++ b/sphinx/util/pycompat.py @@ -5,7 +5,7 @@ Stuff for Python version compatibility. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ @@ -64,6 +64,35 @@ else: return s.encode('ascii', 'backslashreplace') +def execfile_(filepath, _globals): + from sphinx.util.osutil import fs_encoding + # get config source -- 'b' is a no-op under 2.x, while 'U' is + # ignored under 3.x (but 3.x compile() accepts \r\n newlines) + f = open(filepath, 'rbU') + try: + source = f.read() + finally: + f.close() + + # py25,py26,py31 accept only LF eol instead of CRLF + if sys.version_info[:2] in ((2, 5), (2, 6), (3, 1)): + source = source.replace(b('\r\n'), b('\n')) + + # compile to a code object, handle syntax errors + filepath_enc = filepath.encode(fs_encoding) + try: + code = compile(source, filepath_enc, 'exec') + except SyntaxError: + if convert_with_2to3: + # maybe the file uses 2.x syntax; try to refactor to + # 3.x syntax using 2to3 + source = convert_with_2to3(filepath) + code = compile(source, filepath_enc, 'exec') + else: + raise + exec code in _globals + + try: from html import escape as htmlescape except ImportError: @@ -82,6 +111,13 @@ if sys.version_info >= (2, 6): except ImportError: from itertools import izip_longest as zip_longest + import os + relpath = os.path.relpath + del os + + import io + open = io.open + else: # Python < 2.6 from itertools import izip, repeat, chain @@ -114,6 +150,39 @@ else: except IndexError: pass + from os.path import curdir + def relpath(path, start=curdir): + """Return a relative version of a path""" + from os.path import sep, abspath, commonprefix, join, pardir + + if not path: + raise ValueError("no path specified") + + start_list = abspath(start).split(sep) + path_list = abspath(path).split(sep) + + # Work out how much of the filepath is shared by start and path. + i = len(commonprefix([start_list, path_list])) + + rel_list = [pardir] * (len(start_list)-i) + path_list[i:] + if not rel_list: + return start + return join(*rel_list) + del curdir + + from types import MethodType + def open(filename, mode='r', *args, **kw): + newline = kw.pop('newline', None) + mode = mode.replace('t', '') + f = codecs.open(filename, mode, *args, **kw) + if newline is not None: + f._write = f.write + def write(self, text): + text = text.replace(u'\r\n', u'\n').replace(u'\n', newline) + self._write(text) + f.write = MethodType(write, f) + return f + # ------------------------------------------------------------------------------ # Missing builtins and codecs in Python < 2.5 diff --git a/sphinx/util/tags.py b/sphinx/util/tags.py index 7499634da..a6e621407 100644 --- a/sphinx/util/tags.py +++ b/sphinx/util/tags.py @@ -3,7 +3,7 @@ sphinx.util.tags ~~~~~~~~~~~~~~~~ - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/util/texescape.py b/sphinx/util/texescape.py index 1f6f76e66..926208a09 100644 --- a/sphinx/util/texescape.py +++ b/sphinx/util/texescape.py @@ -5,7 +5,7 @@ TeX escaping helper. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/util/websupport.py b/sphinx/util/websupport.py index d9b472135..a20947a8d 100644 --- a/sphinx/util/websupport.py +++ b/sphinx/util/websupport.py @@ -3,7 +3,7 @@ sphinx.util.websupport ~~~~~~~~~~~~~~~~~~~~~~ - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/versioning.py b/sphinx/versioning.py index d45ed1d3f..a16751bb5 100644 --- a/sphinx/versioning.py +++ b/sphinx/versioning.py @@ -6,7 +6,7 @@ Implements the low-level algorithms Sphinx uses for the versioning of doctrees. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ from uuid import uuid4 diff --git a/sphinx/websupport/__init__.py b/sphinx/websupport/__init__.py index 72864a17b..55d56fa03 100644 --- a/sphinx/websupport/__init__.py +++ b/sphinx/websupport/__init__.py @@ -5,7 +5,7 @@ Base Module for web support functions. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/websupport/errors.py b/sphinx/websupport/errors.py index 225b10c86..a0bc07379 100644 --- a/sphinx/websupport/errors.py +++ b/sphinx/websupport/errors.py @@ -5,7 +5,7 @@ Contains Error classes for the web support package. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/websupport/search/__init__.py b/sphinx/websupport/search/__init__.py index 385c3fa97..a5b40117b 100644 --- a/sphinx/websupport/search/__init__.py +++ b/sphinx/websupport/search/__init__.py @@ -5,7 +5,7 @@ Server side search support for the web support package. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ @@ -102,7 +102,7 @@ class BaseSearch(object): res = self.context_re.search(text) if res is None: return '' - context_start = max(res.start() - length/2, 0) + context_start = max(res.start() - int(length/2), 0) context_end = context_start + length context = ''.join([context_start > 0 and '...' or '', text[context_start:context_end], diff --git a/sphinx/websupport/search/nullsearch.py b/sphinx/websupport/search/nullsearch.py index 61f2d2fba..bfa78ce7f 100644 --- a/sphinx/websupport/search/nullsearch.py +++ b/sphinx/websupport/search/nullsearch.py @@ -5,7 +5,7 @@ The default search adapter, does nothing. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/websupport/search/whooshsearch.py b/sphinx/websupport/search/whooshsearch.py index 1ed3d714b..f6343e7e2 100644 --- a/sphinx/websupport/search/whooshsearch.py +++ b/sphinx/websupport/search/whooshsearch.py @@ -5,7 +5,7 @@ Whoosh search adapter. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/websupport/search/xapiansearch.py b/sphinx/websupport/search/xapiansearch.py index 0615be842..6476a71df 100644 --- a/sphinx/websupport/search/xapiansearch.py +++ b/sphinx/websupport/search/xapiansearch.py @@ -5,7 +5,7 @@ Xapian search adapter. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/websupport/storage/__init__.py b/sphinx/websupport/storage/__init__.py index 77292812b..871aa03bb 100644 --- a/sphinx/websupport/storage/__init__.py +++ b/sphinx/websupport/storage/__init__.py @@ -5,7 +5,7 @@ Storage for the websupport package. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/websupport/storage/differ.py b/sphinx/websupport/storage/differ.py index fb3b8dc95..e088f9825 100644 --- a/sphinx/websupport/storage/differ.py +++ b/sphinx/websupport/storage/differ.py @@ -5,7 +5,7 @@ A differ for creating an HTML representations of proposal diffs - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/websupport/storage/sqlalchemy_db.py b/sphinx/websupport/storage/sqlalchemy_db.py index 67136d1ae..587b27413 100644 --- a/sphinx/websupport/storage/sqlalchemy_db.py +++ b/sphinx/websupport/storage/sqlalchemy_db.py @@ -6,7 +6,7 @@ SQLAlchemy table and mapper definitions used by the :class:`sphinx.websupport.storage.sqlalchemystorage.SQLAlchemyStorage`. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/websupport/storage/sqlalchemystorage.py b/sphinx/websupport/storage/sqlalchemystorage.py index e6eccfe97..56528f4be 100644 --- a/sphinx/websupport/storage/sqlalchemystorage.py +++ b/sphinx/websupport/storage/sqlalchemystorage.py @@ -5,7 +5,7 @@ An SQLAlchemy storage backend. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ @@ -116,7 +116,7 @@ class SQLAlchemyStorage(StorageBackend): def get_metadata(self, docname, moderator): session = Session() subquery = session.query( - Comment.id, Comment.node_id, + Comment.node_id, func.count('*').label('comment_count')).group_by( Comment.node_id).subquery() nodes = session.query(Node.id, subquery.c.comment_count).outerjoin( diff --git a/sphinx/writers/__init__.py b/sphinx/writers/__init__.py index 880e4fdbf..40db0d69c 100644 --- a/sphinx/writers/__init__.py +++ b/sphinx/writers/__init__.py @@ -5,6 +5,6 @@ Custom docutils writers. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/writers/html.py b/sphinx/writers/html.py index 2051e38ee..252cedc41 100644 --- a/sphinx/writers/html.py +++ b/sphinx/writers/html.py @@ -5,7 +5,7 @@ docutils writers handling Sphinx' custom nodes. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ @@ -23,7 +23,10 @@ from sphinx.util.smartypants import sphinx_smarty_pants try: from PIL import Image # check for the Python Imaging Library except ImportError: - Image = None + try: + import Image + except ImportError: + Image = None class HTMLWriter(Writer): @@ -200,7 +203,7 @@ class HTMLTranslator(BaseTranslator): def visit_admonition(self, node, name=''): self.body.append(self.starttag( node, 'div', CLASS=('admonition ' + name))) - if name and name != 'seealso': + if name: node.insert(0, nodes.title(name, admonitionlabels[name])) self.set_first_last(node) diff --git a/sphinx/writers/latex.py b/sphinx/writers/latex.py index 4281b6545..6471a61a1 100644 --- a/sphinx/writers/latex.py +++ b/sphinx/writers/latex.py @@ -8,7 +8,7 @@ Much of this code is adapted from Dave Kuhlman's "docpy" writer from his docutils sandbox. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ @@ -100,8 +100,9 @@ class LaTeXWriter(writers.Writer): class ExtBabel(Babel): def get_shorthandoff(self): shortlang = self.language.split('_')[0] - if shortlang in ('de', 'ngerman', 'sl', 'slovene', 'pt', 'portuges', 'es', 'spanish', - 'nl', 'dutch', 'pl', 'polish', 'it', 'italian'): + if shortlang in ('de', 'ngerman', 'sl', 'slovene', 'pt', 'portuges', + 'es', 'spanish', 'nl', 'dutch', 'pl', 'polish', 'it', + 'italian'): return '\\shorthandoff{"}' return '' @@ -206,20 +207,20 @@ class LaTeXTranslator(nodes.NodeVisitor): # pTeX (Japanese TeX) for support if builder.config.language == 'ja': - self.elements['classoptions'] = ',dvipdfm' - # found elements of babel, but this should be above sphinx.sty. - # because pTeX (Japanese TeX) cannot handle this count. - self.elements['babel'] = r'\newcount\pdfoutput\pdfoutput=0' - # to make the pdf with correct encoded hyperref bookmarks - self.elements['preamble'] += \ - r'\AtBeginDvi{\special{pdf:tounicode EUC-UCS2}}' + # use dvipdfmx as default class option in Japanese + self.elements['classoptions'] = ',dvipdfmx' + # disable babel which has not publishing quality in Japanese + self.elements['babel'] = '' + # disable fncychap in Japanese documents + self.elements['fncychap'] = '' else: self.elements['classoptions'] += ',english' print self.elements # allow the user to override them all self.elements.update(builder.config.latex_elements) if self.elements['extraclassoptions']: - self.elements['classoptions'] += ',' + self.elements['extraclassoptions'] + self.elements['classoptions'] += ',' + \ + self.elements['extraclassoptions'] self.highlighter = highlighting.PygmentsBridge('latex', builder.config.pygments_style, builder.config.trim_doctest_flags) @@ -297,7 +298,7 @@ class LaTeXTranslator(nodes.NodeVisitor): if i > 0: ret.append('\\indexspace\n') ret.append('\\bigletter{%s}\n' % - letter.translate(tex_escape_map)) + unicode(letter).translate(tex_escape_map)) for entry in entries: if not entry[3]: continue diff --git a/sphinx/writers/manpage.py b/sphinx/writers/manpage.py index 81f2988b2..cca2d0740 100644 --- a/sphinx/writers/manpage.py +++ b/sphinx/writers/manpage.py @@ -5,7 +5,7 @@ Manual page writer, extended for Sphinx custom nodes. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ @@ -72,6 +72,11 @@ class ManualPageTranslator(BaseTranslator): # since self.append_header() is never called, need to do this here self.body.append(MACRO_DEF) + # Overwrite admonition label translations with our own + for label, translation in admonitionlabels.items(): + self.language.labels[label] = self.deunicode(translation) + + # overwritten -- added quotes around all .TH arguments def header(self): tmpl = (".TH \"%(title_upper)s\" \"%(manual_section)s\"" @@ -193,12 +198,6 @@ class ManualPageTranslator(BaseTranslator): def depart_seealso(self, node): self.depart_admonition(node) - # overwritten -- use our own label translations - def visit_admonition(self, node, name=None): - if name: - self.body.append('.IP %s\n' % - self.deunicode(admonitionlabels.get(name, name))) - def visit_productionlist(self, node): self.ensure_eol() names = [] @@ -341,5 +340,13 @@ class ManualPageTranslator(BaseTranslator): self.body.append(node.astext()) raise nodes.SkipNode + def visit_meta(self, node): + raise nodes.SkipNode + + def visit_inline(self, node): + pass + def depart_inline(self, node): + pass + def unknown_visit(self, node): raise NotImplementedError('Unknown node: ' + node.__class__.__name__) diff --git a/sphinx/writers/texinfo.py b/sphinx/writers/texinfo.py index 5799e0234..a8306c113 100644 --- a/sphinx/writers/texinfo.py +++ b/sphinx/writers/texinfo.py @@ -5,7 +5,7 @@ Custom docutils writer for Texinfo. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ @@ -233,30 +233,31 @@ class TexinfoTranslator(nodes.NodeVisitor): """Generates a unique id for each section. Assigns the attribute ``node_name`` to each section.""" + + def add_node_name(name): + node_id = self.escape_id(name) + nth, suffix = 1, '' + while node_id + suffix in self.written_ids or \ + node_id + suffix in self.node_names: + nth += 1 + suffix = '<%s>' % nth + node_id += suffix + self.written_ids.add(node_id) + self.node_names[node_id] = name + return node_id + # must have a "Top" node self.document['node_name'] = 'Top' - self.node_names['Top'] = 'Top' - self.written_ids.update(('Top', 'top')) + add_node_name('Top') + add_node_name('top') # each index is a node - for name, content in self.indices: - self.node_names[name] = name - self.written_ids.add(name) + self.indices = [(add_node_name(name), content) + for name, content in self.indices] # each section is also a node for section in self.document.traverse(nodes.section): title = section.next_node(nodes.Titular) name = (title and title.astext()) or '' - node_id = self.escape_id(name) or '' - assert node_id and name - nth, suffix = 1, '' - while node_id + suffix in self.written_ids: - nth += 1 - suffix = '<%s>' % nth - node_id += suffix - assert node_id not in self.node_names - assert node_id not in self.written_ids - section['node_name'] = node_id - self.node_names[node_id] = name - self.written_ids.add(node_id) + section['node_name'] = add_node_name(name) def collect_node_menus(self): """Collect the menu entries for each "node" section.""" @@ -371,7 +372,11 @@ class TexinfoTranslator(nodes.NodeVisitor): for entry in entries: name = self.node_names[entry] # special formatting for entries that are divided by an em-dash - parts = reg.split(name, 1) + try: + parts = reg.split(name, 1) + except TypeError: + # could be a gettext proxy + parts = [name] if len(parts) == 2: name, desc = parts else: @@ -450,8 +455,7 @@ class TexinfoTranslator(nodes.NodeVisitor): self.builder.docnames) if not content: continue - node_name = self.escape_id(indexcls.localname) - self.indices.append((node_name, + self.indices.append((indexcls.localname, generate(content, collapsed))) self.indices.append((_('Index'), '\n@printindex ge\n')) @@ -1175,7 +1179,7 @@ class TexinfoTranslator(nodes.NodeVisitor): for id in production.get('ids'): self.add_anchor(id, production) s = production['tokenname'].ljust(maxlen) + ' ::=' - lastname = production['tokenname'] + ##lastname = production['tokenname'] else: s = '%s ' % (' '*maxlen) self.body.append(self.escape(s)) diff --git a/sphinx/writers/text.py b/sphinx/writers/text.py index e5ab070c7..1f90497e7 100644 --- a/sphinx/writers/text.py +++ b/sphinx/writers/text.py @@ -5,14 +5,16 @@ Custom docutils writer for plain text. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ import os import re import textwrap +from itertools import groupby from docutils import nodes, writers +from docutils.utils import column_width from sphinx import addnodes from sphinx.locale import admonitionlabels, versionlabels, _ @@ -27,6 +29,98 @@ class TextWrapper(textwrap.TextWrapper): r'[^\s\w]*\w+[a-zA-Z]-(?=\w+[a-zA-Z])|' # hyphenated words r'(?<=[\w\!\"\'\&\.\,\?])-{2,}(?=\w))') # em-dash + def _wrap_chunks(self, chunks): + """_wrap_chunks(chunks : [string]) -> [string] + + Original _wrap_chunks use len() to calculate width. + This method respect to wide/fullwidth characters for width adjustment. + """ + drop_whitespace = getattr(self, 'drop_whitespace', True) #py25 compat + lines = [] + if self.width <= 0: + raise ValueError("invalid width %r (must be > 0)" % self.width) + + chunks.reverse() + + while chunks: + cur_line = [] + cur_len = 0 + + if lines: + indent = self.subsequent_indent + else: + indent = self.initial_indent + + width = self.width - column_width(indent) + + if drop_whitespace and chunks[-1].strip() == '' and lines: + del chunks[-1] + + while chunks: + l = column_width(chunks[-1]) + + if cur_len + l <= width: + cur_line.append(chunks.pop()) + cur_len += l + + else: + break + + if chunks and column_width(chunks[-1]) > width: + self._handle_long_word(chunks, cur_line, cur_len, width) + + if drop_whitespace and cur_line and cur_line[-1].strip() == '': + del cur_line[-1] + + if cur_line: + lines.append(indent + ''.join(cur_line)) + + return lines + + def _break_word(self, word, space_left): + """_break_word(word : string, space_left : int) -> (string, string) + + Break line by unicode width instead of len(word). + """ + total = 0 + for i,c in enumerate(word): + total += column_width(c) + if total > space_left: + return word[:i-1], word[i-1:] + return word, '' + + def _split(self, text): + """_split(text : string) -> [string] + + Override original method that only split by 'wordsep_re'. + This '_split' split wide-characters into chunk by one character. + """ + split = lambda t: textwrap.TextWrapper._split(self, t) + chunks = [] + for chunk in split(text): + for w, g in groupby(chunk, column_width): + if w == 1: + chunks.extend(split(''.join(g))) + else: + chunks.extend(list(g)) + return chunks + + def _handle_long_word(self, reversed_chunks, cur_line, cur_len, width): + """_handle_long_word(chunks : [string], + cur_line : [string], + cur_len : int, width : int) + + Override original method for using self._break_word() instead of slice. + """ + space_left = max(width - cur_len, 1) + if self.break_long_words: + l, r = self._break_word(reversed_chunks[-1], space_left) + cur_line.append(l) + reversed_chunks[-1] = r + + elif not cur_line: + cur_line.append(reversed_chunks.pop()) + MAXWIDTH = 70 STDINDENT = 3 @@ -71,6 +165,7 @@ class TextTranslator(nodes.NodeVisitor): self.stateindent = [0] self.list_counter = [] self.sectionlevel = 0 + self.lineblocklevel = 0 self.table = None def add_text(self, text): @@ -164,7 +259,8 @@ class TextTranslator(nodes.NodeVisitor): char = '^' text = ''.join(x[1] for x in self.states.pop() if x[0] == -1) self.stateindent.pop() - self.states[-1].append((0, ['', text, '%s' % (char * len(text)), ''])) + self.states[-1].append( + (0, ['', text, '%s' % (char * column_width(text)), ''])) def visit_subtitle(self, node): pass @@ -270,11 +366,6 @@ class TextTranslator(nodes.NodeVisitor): self.end_state(wrap=False) raise nodes.SkipNode - def visit_seealso(self, node): - self.new_state() - def depart_seealso(self, node): - self.end_state(first='') - def visit_footnote(self, node): self._footnote = node.children[0].astext().strip() self.new_state(len(self._footnote) + 3) @@ -293,6 +384,11 @@ class TextTranslator(nodes.NodeVisitor): def visit_label(self, node): raise nodes.SkipNode + def visit_legend(self, node): + pass + def depart_legend(self, node): + pass + # XXX: option list could use some better styling def visit_option_list(self, node): @@ -390,7 +486,7 @@ class TextTranslator(nodes.NodeVisitor): for i, cell in enumerate(line): par = my_wrap(cell, width=colwidths[i]) if par: - maxwidth = max(map(len, par)) + maxwidth = max(map(column_width, par)) else: maxwidth = 0 realwidths[i] = max(realwidths[i], maxwidth) @@ -410,7 +506,9 @@ class TextTranslator(nodes.NodeVisitor): out = ['|'] for i, cell in enumerate(line): if cell: - out.append(' ' + cell.ljust(realwidths[i]+1)) + adjust_len = len(cell) - column_width(cell) + out.append(' ' + cell.ljust( + realwidths[i] + 1 + adjust_len)) else: out.append(' ' * (realwidths[i] + 2)) out.append('|') @@ -572,6 +670,8 @@ class TextTranslator(nodes.NodeVisitor): depart_tip = _make_depart_admonition('tip') visit_warning = _visit_admonition depart_warning = _make_depart_admonition('warning') + visit_seealso = _visit_admonition + depart_seealso = _make_depart_admonition('seealso') def visit_versionmodified(self, node): self.new_state(0) @@ -593,14 +693,18 @@ class TextTranslator(nodes.NodeVisitor): self.end_state(wrap=False) def visit_line_block(self, node): - self.new_state(0) + self.new_state() + self.lineblocklevel += 1 def depart_line_block(self, node): - self.end_state(wrap=False) + self.lineblocklevel -= 1 + self.end_state(wrap=False, end=None) + if not self.lineblocklevel: + self.add_text('\n') def visit_line(self, node): pass def depart_line(self, node): - pass + self.add_text('\n') def visit_block_quote(self, node): self.new_state() @@ -709,6 +813,11 @@ class TextTranslator(nodes.NodeVisitor): def depart_inline(self, node): pass + def visit_container(self, node): + pass + def depart_container(self, node): + pass + def visit_problematic(self, node): self.add_text('>>') def depart_problematic(self, node): diff --git a/sphinx/writers/websupport.py b/sphinx/writers/websupport.py index f75cd47b1..71a9ba00d 100644 --- a/sphinx/writers/websupport.py +++ b/sphinx/writers/websupport.py @@ -5,7 +5,7 @@ sphinx.websupport writer that adds comment-related annotations. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/sphinx/writers/xml.py b/sphinx/writers/xml.py new file mode 100644 index 000000000..9f1fc7626 --- /dev/null +++ b/sphinx/writers/xml.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +""" + sphinx.writers.xml + ~~~~~~~~~~~~~~~~~~ + + Docutils-native XML and pseudo-XML writers. + + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" + +from docutils import writers +from docutils.writers.docutils_xml import Writer as BaseXMLWriter + + +class XMLWriter(BaseXMLWriter): + + def __init__(self, builder): + BaseXMLWriter.__init__(self) + self.builder = builder + + def translate(self, *args, **kwargs): + self.document.settings.newlines = \ + self.document.settings.indents = \ + self.builder.env.config.xml_pretty + self.document.settings.xml_declaration = True + self.document.settings.doctype_declaration = True + return BaseXMLWriter.translate(self) + + +class PseudoXMLWriter(writers.Writer): + + supported = ('pprint', 'pformat', 'pseudoxml') + """Formats this writer supports.""" + + config_section = 'pseudoxml writer' + config_section_dependencies = ('writers',) + + output = None + """Final translated form of `document`.""" + + def __init__(self, builder): + writers.Writer.__init__(self) + self.builder = builder + + def translate(self): + self.output = self.document.pformat() + + def supports(self, format): + """This writer supports all format-specific elements.""" + return True diff --git a/tests/path.py b/tests/path.py index 8e9afeaa8..bd0552d70 100644 --- a/tests/path.py +++ b/tests/path.py @@ -16,16 +16,16 @@ from codecs import open FILESYSTEMENCODING = sys.getfilesystemencoding() or sys.getdefaultencoding() -class path(str): +class path(unicode): """ Represents a path which behaves like a string. """ if sys.version_info < (3, 0): def __new__(cls, s, encoding=FILESYSTEMENCODING, errors='strict'): - if isinstance(s, unicode): - s = s.encode(encoding, errors=errors) - return str.__new__(cls, s) - return str.__new__(cls, s) + if isinstance(s, str): + s = s.decode(encoding, errors) + return unicode.__new__(cls, s) + return unicode.__new__(cls, s) @property def parent(self): @@ -193,4 +193,4 @@ class path(str): __div__ = __truediv__ = joinpath def __repr__(self): - return '%s(%s)' % (self.__class__.__name__, str.__repr__(self)) + return '%s(%s)' % (self.__class__.__name__, unicode.__repr__(self)) diff --git a/tests/root/Makefile b/tests/root/Makefile index e9c11d067..7954bc7cb 100644 --- a/tests/root/Makefile +++ b/tests/root/Makefile @@ -23,7 +23,7 @@ help: @echo " linkcheck to check all external links for integrity" clean: - -rm -rf _build/* + rm -rf _build/* html: mkdir -p _build/html _build/doctrees diff --git a/tests/root/autodoc.txt b/tests/root/autodoc.txt index 5c03f947c..d4b3404c4 100644 --- a/tests/root/autodoc.txt +++ b/tests/root/autodoc.txt @@ -32,3 +32,16 @@ Just testing a few autodoc possibilities... :noindex: .. autoclass:: MarkupError + + +.. currentmodule:: test_autodoc + +.. autoclass:: InstAttCls + :members: + + All members (5 total) + +.. autoclass:: InstAttCls + :members: ca1, ia1 + + Specific members (2 total) diff --git a/tests/root/conf.py b/tests/root/conf.py index b97ddfcc1..37b9127e7 100644 --- a/tests/root/conf.py +++ b/tests/root/conf.py @@ -3,6 +3,7 @@ import sys, os sys.path.append(os.path.abspath('.')) +sys.path.append(os.path.abspath('..')) extensions = ['sphinx.ext.autodoc', 'sphinx.ext.jsmath', 'sphinx.ext.todo', 'sphinx.ext.coverage', 'sphinx.ext.autosummary', @@ -54,6 +55,11 @@ texinfo_documents = [ 'Georg Brandl \\and someone else', 'Sphinx Testing', 'Miscellaneous'), ] +man_pages = [ + ('contents', 'SphinxTests', 'Sphinx Tests Documentation', + 'Georg Brandl and someone else', 1), +] + value_from_conf_py = 84 coverage_c_path = ['special/*.h'] @@ -67,6 +73,28 @@ extlinks = {'issue': ('http://bugs.python.org/issue%s', 'issue '), # modify tags from conf.py tags.add('confpytag') +# -- linkcode + +if 'test_linkcode' in tags: + import glob + + extensions.remove('sphinx.ext.viewcode') + extensions.append('sphinx.ext.linkcode') + + exclude_patterns.extend(glob.glob('*.txt') + glob.glob('*/*.txt')) + exclude_patterns.remove('contents.txt') + exclude_patterns.remove('objects.txt') + + def linkcode_resolve(domain, info): + if domain == 'py': + fn = info['module'].replace('.', '/') + return "http://foobar/source/%s.py" % fn + elif domain == "js": + return "http://foobar/js/" + info['fullname'] + elif domain in ("c", "cpp"): + return "http://foobar/%s/%s" % (domain, "".join(info['names'])) + else: + raise AssertionError() # -- extension API diff --git a/tests/root/contents.txt b/tests/root/contents.txt index 280953b46..de60ec6dd 100644 --- a/tests/root/contents.txt +++ b/tests/root/contents.txt @@ -27,6 +27,7 @@ Contents: doctest extensions versioning/index + footnote Python diff --git a/tests/root/footnote.txt b/tests/root/footnote.txt new file mode 100644 index 000000000..c1359dfe4 --- /dev/null +++ b/tests/root/footnote.txt @@ -0,0 +1,40 @@ +:tocdepth: 2 + +Testing footnote and citation +================================ +.. #1058 footnote-backlinks-do-not-work + +numbered footnote +-------------------- + +[1]_ + +auto-numbered footnote +------------------------------ + +[#]_ + +named footnote +-------------------- + +[#foo]_ + +citation +-------------------- + +[bar]_ + +footenotes +-------------------- + +.. rubric:: Footnotes + +.. [1] numbered + +.. [#] auto numbered + +.. [#foo] named + +.. rubric:: Citations + +.. [bar] cite diff --git a/tests/root/markup.txt b/tests/root/markup.txt index dde13a6b5..cbfbbbe3d 100644 --- a/tests/root/markup.txt +++ b/tests/root/markup.txt @@ -191,6 +191,10 @@ Figures My caption of the figure + My description paragraph of the figure. + + Description paragraph is wraped with legend node. + Version markup -------------- diff --git a/tests/roots/test-intl/bom.po b/tests/roots/test-intl/bom.po new file mode 100644 index 000000000..c6025eb1e --- /dev/null +++ b/tests/roots/test-intl/bom.po @@ -0,0 +1,12 @@ +#, fuzzy +msgid "" +msgstr "" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +msgid "File with UTF-8 BOM" +msgstr "Datei mit UTF-8" + +msgid "This file has a UTF-8 \"BOM\"." +msgstr "This file has umlauts: äöü." diff --git a/tests/roots/test-intl/bom.txt b/tests/roots/test-intl/bom.txt new file mode 100644 index 000000000..3fea824f8 --- /dev/null +++ b/tests/roots/test-intl/bom.txt @@ -0,0 +1,5 @@ +File with UTF-8 BOM +=================== + +This file has a UTF-8 "BOM". + diff --git a/tests/roots/test-intl/conf.py b/tests/roots/test-intl/conf.py new file mode 100644 index 000000000..457c5056f --- /dev/null +++ b/tests/roots/test-intl/conf.py @@ -0,0 +1,7 @@ +# -*- coding: utf-8 -*- + +import sys, os + +project = 'Sphinx intl ' +source_suffix = '.txt' +keep_warnings = True diff --git a/tests/roots/test-intl/contents.txt b/tests/roots/test-intl/contents.txt new file mode 100644 index 000000000..298beb6ce --- /dev/null +++ b/tests/roots/test-intl/contents.txt @@ -0,0 +1,21 @@ +CONTENTS +======== + +.. toctree:: + :maxdepth: 2 + :numbered: + + subdir/contents + bom + warnings + footnote + external_links + refs_inconsistency + literalblock + seealso + definition_terms + figure_caption + index_entries + role_xref + glossary_terms + glossary_terms_inconsistency diff --git a/tests/roots/test-intl/definition_terms.po b/tests/roots/test-intl/definition_terms.po new file mode 100644 index 000000000..2c3a3bca4 --- /dev/null +++ b/tests/roots/test-intl/definition_terms.po @@ -0,0 +1,32 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2012, foof +# This file is distributed under the same license as the foo package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: sphinx 1.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2013-01-01 05:00\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +msgid "i18n with definition terms" +msgstr "I18N WITH DEFINITION TERMS" + +msgid "Some term" +msgstr "SOME TERM" + +msgid "The corresponding definition" +msgstr "THE CORRESPONDING DEFINITION" + +msgid "Some other term" +msgstr "SOME OTHER TERM" + +msgid "The corresponding definition #2" +msgstr "THE CORRESPONDING DEFINITION #2" diff --git a/tests/roots/test-intl/definition_terms.txt b/tests/roots/test-intl/definition_terms.txt new file mode 100644 index 000000000..9891401d1 --- /dev/null +++ b/tests/roots/test-intl/definition_terms.txt @@ -0,0 +1,11 @@ +:tocdepth: 2 + +i18n with definition terms +========================== + +Some term + The corresponding definition + +Some other term + The corresponding definition #2 + diff --git a/tests/roots/test-intl/external_links.po b/tests/roots/test-intl/external_links.po new file mode 100644 index 000000000..4cd19ddab --- /dev/null +++ b/tests/roots/test-intl/external_links.po @@ -0,0 +1,32 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2012, foof +# This file is distributed under the same license as the foo package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: sphinx 1.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-11-22 08:28\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +msgid "i18n with external links" +msgstr "EXTERNAL LINKS" + +msgid "External link to Python_." +msgstr "EXTERNAL LINK TO Python_." + +msgid "Internal link to `i18n with external links`_." +msgstr "`EXTERNAL LINKS`_ IS INTERNAL LINK." + +msgid "Inline link by `Sphinx `_." +msgstr "INLINE LINK BY `SPHINX `_." + +msgid "Unnamed link__." +msgstr "UNNAMED LINK__." diff --git a/tests/roots/test-intl/external_links.txt b/tests/roots/test-intl/external_links.txt new file mode 100644 index 000000000..7ac1db02e --- /dev/null +++ b/tests/roots/test-intl/external_links.txt @@ -0,0 +1,13 @@ +:tocdepth: 2 + +i18n with external links +======================== +.. #1044 external-links-dont-work-in-localized-html + +* External link to Python_. +* Internal link to `i18n with external links`_. +* Inline link by `Sphinx `_. +* Unnamed link__. + +.. _Python: http://python.org +.. __: http://google.com diff --git a/tests/roots/test-intl/figure_caption.po b/tests/roots/test-intl/figure_caption.po new file mode 100644 index 000000000..01b4c041e --- /dev/null +++ b/tests/roots/test-intl/figure_caption.po @@ -0,0 +1,29 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2012, foof +# This file is distributed under the same license as the foo package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: sphinx 1.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2013-01-04 7:00\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +msgid "i18n with figure caption" +msgstr "I18N WITH FIGURE CAPTION" + +msgid "My caption of the figure" +msgstr "MY CAPTION OF THE FIGURE" + +msgid "My description paragraph1 of the figure." +msgstr "MY DESCRIPTION PARAGRAPH1 OF THE FIGURE." + +msgid "My description paragraph2 of the figure." +msgstr "MY DESCRIPTION PARAGRAPH2 OF THE FIGURE." diff --git a/tests/roots/test-intl/figure_caption.txt b/tests/roots/test-intl/figure_caption.txt new file mode 100644 index 000000000..75567b3a1 --- /dev/null +++ b/tests/roots/test-intl/figure_caption.txt @@ -0,0 +1,12 @@ +:tocdepth: 2 + +i18n with figure caption +======================== + +.. figure:: i18n.png + + My caption of the figure + + My description paragraph1 of the figure. + + My description paragraph2 of the figure. diff --git a/tests/roots/test-intl/footnote.po b/tests/roots/test-intl/footnote.po new file mode 100644 index 000000000..47f8d3db4 --- /dev/null +++ b/tests/roots/test-intl/footnote.po @@ -0,0 +1,33 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2012, foof +# This file is distributed under the same license as the foo package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: sphinx 1.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-11-22 08:28\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +msgid "i18n with Footnote" +msgstr "I18N WITH FOOTNOTE" + +msgid "[100]_ Contents [#]_ for `i18n with Footnote`_ [ref]_" +msgstr "`I18N WITH FOOTNOTE`_ INCLUDE THIS CONTENTS [ref]_ [#]_ [100]_" + +msgid "This is a auto numbered footnote." +msgstr "THIS IS A AUTO NUMBERED FOOTNOTE." + +msgid "This is a named footnote." +msgstr "THIS IS A NAMED FOOTNOTE." + +msgid "This is a numbered footnote." +msgstr "THIS IS A NUMBERED FOOTNOTE." + diff --git a/tests/roots/test-intl/footnote.txt b/tests/roots/test-intl/footnote.txt new file mode 100644 index 000000000..3ef76bbaa --- /dev/null +++ b/tests/roots/test-intl/footnote.txt @@ -0,0 +1,11 @@ +:tocdepth: 2 + +i18n with Footnote +================== +.. #955 cant-build-html-with-footnotes-when-using + +[100]_ Contents [#]_ for `i18n with Footnote`_ [ref]_ + +.. [#] This is a auto numbered footnote. +.. [ref] This is a named footnote. +.. [100] This is a numbered footnote. diff --git a/tests/roots/test-intl/glossary_terms.po b/tests/roots/test-intl/glossary_terms.po new file mode 100644 index 000000000..1ffcaeb20 --- /dev/null +++ b/tests/roots/test-intl/glossary_terms.po @@ -0,0 +1,35 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2012, foof +# This file is distributed under the same license as the foo package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: sphinx 1.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2013-01-29 14:10\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +msgid "i18n with glossary terms" +msgstr "I18N WITH GLOSSARY TERMS" + +msgid "Some term" +msgstr "SOME NEW TERM" + +msgid "The corresponding glossary" +msgstr "THE CORRESPONDING GLOSSARY" + +msgid "Some other term" +msgstr "SOME OTHER NEW TERM" + +msgid "The corresponding glossary #2" +msgstr "THE CORRESPONDING GLOSSARY #2" + +msgid "link to :term:`Some term`." +msgstr "LINK TO :term:`SOME NEW TERM`." diff --git a/tests/roots/test-intl/glossary_terms.txt b/tests/roots/test-intl/glossary_terms.txt new file mode 100644 index 000000000..a6e16c948 --- /dev/null +++ b/tests/roots/test-intl/glossary_terms.txt @@ -0,0 +1,14 @@ +:tocdepth: 2 + +i18n with glossary terms +======================== + +.. glossary:: + + Some term + The corresponding glossary + + Some other term + The corresponding glossary #2 + +link to :term:`Some term`. diff --git a/tests/roots/test-intl/glossary_terms_inconsistency.po b/tests/roots/test-intl/glossary_terms_inconsistency.po new file mode 100644 index 000000000..5e3016578 --- /dev/null +++ b/tests/roots/test-intl/glossary_terms_inconsistency.po @@ -0,0 +1,23 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2012, foof +# This file is distributed under the same license as the foo package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: sphinx 1.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2013-01-29 14:10\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +msgid "i18n with glossary terms inconsistency" +msgstr "I18N WITH GLOSSARY TERMS INCONSISTENCY" + +msgid "link to :term:`Some term` and :term:`Some other term`." +msgstr "LINK TO :term:`SOME NEW TERM`." diff --git a/tests/roots/test-intl/glossary_terms_inconsistency.txt b/tests/roots/test-intl/glossary_terms_inconsistency.txt new file mode 100644 index 000000000..837411b6f --- /dev/null +++ b/tests/roots/test-intl/glossary_terms_inconsistency.txt @@ -0,0 +1,6 @@ +:tocdepth: 2 + +i18n with glossary terms inconsistency +====================================== + +1. link to :term:`Some term` and :term:`Some other term`. diff --git a/tests/roots/test-intl/i18n.png b/tests/roots/test-intl/i18n.png new file mode 100644 index 000000000..72c12d13f Binary files /dev/null and b/tests/roots/test-intl/i18n.png differ diff --git a/tests/roots/test-intl/index_entries.po b/tests/roots/test-intl/index_entries.po new file mode 100644 index 000000000..6da9a813d --- /dev/null +++ b/tests/roots/test-intl/index_entries.po @@ -0,0 +1,77 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2013, foo +# This file is distributed under the same license as the foo package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: foo foo\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2013-01-05 18:10\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +msgid "i18n with index entries" +msgstr "" + +msgid "index target section" +msgstr "" + +msgid "this is :index:`Newsletter` target paragraph." +msgstr "THIS IS :index:`NEWSLETTER` TARGET PARAGRAPH." + +msgid "various index entries" +msgstr "" + +msgid "That's all." +msgstr "" + +msgid "Mailing List" +msgstr "MAILING LIST" + +msgid "Newsletter" +msgstr "NEWSLETTER" + +msgid "Recipients List" +msgstr "RECIPIENTS LIST" + +msgid "First" +msgstr "FIRST" + +msgid "Second" +msgstr "SECOND" + +msgid "Third" +msgstr "THIRD" + +msgid "Entry" +msgstr "ENTRY" + +msgid "See" +msgstr "SEE" + +msgid "Module" +msgstr "MODULE" + +msgid "Keyword" +msgstr "KEYWORD" + +msgid "Operator" +msgstr "OPERATOR" + +msgid "Object" +msgstr "OBJECT" + +msgid "Exception" +msgstr "EXCEPTION" + +msgid "Statement" +msgstr "STATEMENT" + +msgid "Builtin" +msgstr "BUILTIN" diff --git a/tests/roots/test-intl/index_entries.txt b/tests/roots/test-intl/index_entries.txt new file mode 100644 index 000000000..c914a4b43 --- /dev/null +++ b/tests/roots/test-intl/index_entries.txt @@ -0,0 +1,31 @@ +:tocdepth: 2 + +i18n with index entries +======================= + +.. index:: + single: Mailing List + pair: Newsletter; Recipients List + +index target section +-------------------- + +this is :index:`Newsletter` target paragraph. + + +various index entries +--------------------- + +.. index:: + triple: First; Second; Third + see: Entry; Mailing List + seealso: See; Newsletter + module: Module + keyword: Keyword + operator: Operator + object: Object + exception: Exception + statement: Statement + builtin: Builtin + +That's all. diff --git a/tests/roots/test-intl/literalblock.po b/tests/roots/test-intl/literalblock.po new file mode 100644 index 000000000..8ea83b3bd --- /dev/null +++ b/tests/roots/test-intl/literalblock.po @@ -0,0 +1,30 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2012, foof +# This file is distributed under the same license as the foo package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: sphinx 1.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-11-22 08:28\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +msgid "i18n with literal block" +msgstr "I18N WITH LITERAL BLOCK" + +msgid "Correct literal block::" +msgstr "CORRECT LITERAL BLOCK::" + +msgid "Missing literal block::" +msgstr "MISSING LITERAL BLOCK::" + +msgid "That's all." +msgstr "THAT'S ALL." + diff --git a/tests/roots/test-intl/literalblock.txt b/tests/roots/test-intl/literalblock.txt new file mode 100644 index 000000000..c9c710997 --- /dev/null +++ b/tests/roots/test-intl/literalblock.txt @@ -0,0 +1,13 @@ +:tocdepth: 2 + +i18n with literal block +========================= + +Correct literal block:: + + this is + literal block + +Missing literal block:: + +That's all. diff --git a/tests/roots/test-intl/refs_inconsistency.po b/tests/roots/test-intl/refs_inconsistency.po new file mode 100644 index 000000000..9cab687fd --- /dev/null +++ b/tests/roots/test-intl/refs_inconsistency.po @@ -0,0 +1,39 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2012, foof +# This file is distributed under the same license as the foo package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: sphinx 1.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-12-05 08:28\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +msgid "i18n with refs inconsistency" +msgstr "I18N WITH REFS INCONSISTENCY" + +msgid "[100]_ for [#]_ footnote [ref2]_." +msgstr "FOR FOOTNOTE [ref2]_." + +msgid "for reference_." +msgstr "reference_ FOR reference_." + +msgid "normal text." +msgstr "ORPHAN REFERENCE: `I18N WITH REFS INCONSISTENCY`_." + +msgid "This is a auto numbered footnote." +msgstr "THIS IS A AUTO NUMBERED FOOTNOTE." + +msgid "This is a named footnote." +msgstr "THIS IS A NAMED FOOTNOTE." + +msgid "This is a numbered footnote." +msgstr "THIS IS A NUMBERED FOOTNOTE." + diff --git a/tests/roots/test-intl/refs_inconsistency.txt b/tests/roots/test-intl/refs_inconsistency.txt new file mode 100644 index 000000000..c65c5b458 --- /dev/null +++ b/tests/roots/test-intl/refs_inconsistency.txt @@ -0,0 +1,13 @@ +:tocdepth: 2 + +i18n with refs inconsistency +============================= + +* [100]_ for [#]_ footnote [ref2]_. +* for reference_. +* normal text. + +.. [#] This is a auto numbered footnote. +.. [ref2] This is a named footnote. +.. [100] This is a numbered footnote. +.. _reference: http://www.example.com diff --git a/tests/roots/test-intl/role_xref.po b/tests/roots/test-intl/role_xref.po new file mode 100644 index 000000000..e7a348b36 --- /dev/null +++ b/tests/roots/test-intl/role_xref.po @@ -0,0 +1,23 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2012, foof +# This file is distributed under the same license as the foo package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: sphinx 1.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2013-02-04 14:00\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +msgid "i18n role xref" +msgstr "I18N ROCK'N ROLE XREF" + +msgid "link to :term:`Some term`, :ref:`i18n-role-xref`, :doc:`contents`." +msgstr "LINK TO :ref:`i18n-role-xref`, :doc:`contents`, :term:`SOME NEW TERM`." diff --git a/tests/roots/test-intl/role_xref.txt b/tests/roots/test-intl/role_xref.txt new file mode 100644 index 000000000..382b740c9 --- /dev/null +++ b/tests/roots/test-intl/role_xref.txt @@ -0,0 +1,9 @@ +:tocdepth: 2 + +.. _i18n-role-xref: + +i18n role xref +============== + +link to :term:`Some term`, :ref:`i18n-role-xref`, :doc:`contents`. + diff --git a/tests/roots/test-intl/seealso.po b/tests/roots/test-intl/seealso.po new file mode 100644 index 000000000..d3b27e51b --- /dev/null +++ b/tests/roots/test-intl/seealso.po @@ -0,0 +1,33 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2010, Georg Brandl & Team +# This file is distributed under the same license as the Sphinx package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: Sphinx 0.6\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-12-16 06:06\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +msgid "i18n with seealso" +msgstr "I18N WITH SEEALSO" + +msgid "short text 1" +msgstr "SHORT TEXT 1" + +msgid "long text 1" +msgstr "LONG TEXT 1" + +msgid "short text 2" +msgstr "SHORT TEXT 2" + +msgid "long text 2" +msgstr "LONG TEXT 2" + diff --git a/tests/roots/test-intl/seealso.txt b/tests/roots/test-intl/seealso.txt new file mode 100644 index 000000000..ed8859972 --- /dev/null +++ b/tests/roots/test-intl/seealso.txt @@ -0,0 +1,15 @@ +:tocdepth: 2 + +i18n with seealso +============================ +.. #960 directive-seelaso-ignored-in-the-gettext + +.. seealso:: short text 1 + +.. seealso:: + + long text 1 + +.. seealso:: short text 2 + + long text 2 diff --git a/tests/roots/test-intl/subdir/contents.txt b/tests/roots/test-intl/subdir/contents.txt new file mode 100644 index 000000000..b6509bafb --- /dev/null +++ b/tests/roots/test-intl/subdir/contents.txt @@ -0,0 +1,2 @@ +subdir contents +=============== diff --git a/tests/roots/test-intl/warnings.po b/tests/roots/test-intl/warnings.po new file mode 100644 index 000000000..bf82510ee --- /dev/null +++ b/tests/roots/test-intl/warnings.po @@ -0,0 +1,23 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2010, Georg Brandl & Team +# This file is distributed under the same license as the Sphinx package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: Sphinx 0.6\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2013-02-04 13:06\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +msgid "i18n with reST warnings" +msgstr "I18N WITH REST WARNINGS" + +msgid "line of ``literal`` markup." +msgstr "LINE OF ``BROKEN LITERAL MARKUP." diff --git a/tests/roots/test-intl/warnings.txt b/tests/roots/test-intl/warnings.txt new file mode 100644 index 000000000..a80fe183d --- /dev/null +++ b/tests/roots/test-intl/warnings.txt @@ -0,0 +1,5 @@ +i18n with reST warnings +======================== + +line of ``literal`` markup. + diff --git a/tests/roots/test-only-directive/conf.py b/tests/roots/test-only-directive/conf.py new file mode 100644 index 000000000..bcb4305da --- /dev/null +++ b/tests/roots/test-only-directive/conf.py @@ -0,0 +1,2 @@ + +project = 'test-only-directive' diff --git a/tests/roots/test-only-directive/contents.rst b/tests/roots/test-only-directive/contents.rst new file mode 100644 index 000000000..9a93be9e7 --- /dev/null +++ b/tests/roots/test-only-directive/contents.rst @@ -0,0 +1,6 @@ +test-only-directive +=================== + +.. toctree:: + + only diff --git a/tests/roots/test-only-directive/only.rst b/tests/roots/test-only-directive/only.rst new file mode 100644 index 000000000..4a3eb48a6 --- /dev/null +++ b/tests/roots/test-only-directive/only.rst @@ -0,0 +1,203 @@ + +1. Sections in only directives +============================== + +Testing sections in only directives. + +.. only:: nonexisting_tag + + Skipped Section + --------------- + Should not be here. + +.. only:: not nonexisting_tag + + 1.1. Section + ------------ + Should be here. + +1.2. Section +------------ + +.. only:: not nonexisting_tag + + 1.2.1. Subsection + ~~~~~~~~~~~~~~~~~ + Should be here. + +.. only:: nonexisting_tag + + Skipped Subsection + ~~~~~~~~~~~~~~~~~~ + Should not be here. + +1.3. Section +------------ + +1.3.1. Subsection +~~~~~~~~~~~~~~~~~ +Should be here. + +1.4. Section +------------ + +.. only:: not nonexisting_tag + + 1.4.1. Subsection + ~~~~~~~~~~~~~~~~~ + Should be here. + +1.5. Section +------------ + +.. only:: not nonexisting_tag + + 1.5.1. Subsection + ~~~~~~~~~~~~~~~~~ + Should be here. + +1.5.2. Subsection +~~~~~~~~~~~~~~~~~ +Should be here. + +1.6. Section +------------ + +1.6.1. Subsection +~~~~~~~~~~~~~~~~~ +Should be here. + +.. only:: not nonexisting_tag + + 1.6.2. Subsection + ~~~~~~~~~~~~~~~~~ + Should be here. + +1.6.3. Subsection +~~~~~~~~~~~~~~~~~ +Should be here. + +1.7. Section +------------ + +1.7.1. Subsection +~~~~~~~~~~~~~~~~~ +Should be here. + +.. only:: not nonexisting_tag + + 1.7.1.1. Subsubsection + ...................... + Should be here. + +1.8. Section +------------ + +1.8.1. Subsection +~~~~~~~~~~~~~~~~~ +Should be here. + +1.8.1.1. Subsubsection +...................... +Should be here. + +.. only:: not nonexisting_tag + + 1.8.1.2. Subsubsection + ...................... + Should be here. + +1.9. Section +------------ + +.. only:: nonexisting_tag + + Skipped Subsection + ~~~~~~~~~~~~~~~~~~ + +1.9.1. Subsection +~~~~~~~~~~~~~~~~~ +Should be here. + +1.9.1.1. Subsubsection +...................... +Should be here. + +.. only:: not nonexisting_tag + + 1.10. Section + ------------- + Should be here. + +1.11. Section +------------- + +Text before subsection 11.1. + +.. only:: not nonexisting_tag + + More text before subsection 11.1. + + 1.11.1. Subsection + ~~~~~~~~~~~~~~~~~~ + Should be here. + +Text after subsection 11.1. + +.. only:: not nonexisting_tag + + 1.12. Section + ------------- + Should be here. + + 1.12.1. Subsection + ~~~~~~~~~~~~~~~~~~ + Should be here. + + 1.13. Section + ------------- + Should be here. + +.. only:: not nonexisting_tag + + 1.14. Section + ------------- + Should be here. + + .. only:: not nonexisting_tag + + 1.14.1. Subsection + ~~~~~~~~~~~~~~~~~~ + Should be here. + + 1.15. Section + ------------- + Should be here. + +.. only:: nonexisting_tag + + Skipped document level heading + ============================== + Should not be here. + +.. only:: not nonexisting_tag + + 2. Included document level heading + ================================== + Should be here. + +3. Document level heading +========================= +Should be here. + +.. only:: nonexisting_tag + + Skipped document level heading + ============================== + Should not be here. + +.. only:: not nonexisting_tag + + 4. Another included document level heading + ========================================== + Should be here. diff --git a/tests/run.py b/tests/run.py index 8b3bf844d..c0ae0d236 100755 --- a/tests/run.py +++ b/tests/run.py @@ -6,7 +6,7 @@ This script runs the Sphinx unit test suite. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ @@ -18,14 +18,14 @@ if sys.version_info >= (3, 0): from distutils.util import copydir_run_2to3 testroot = path.dirname(__file__) or '.' if 'BUILD_TEST_PATH' in environ: - # for tox test. + # for tox testing newroot = environ['BUILD_TEST_PATH'] - # tox install sphinx package, not need sys.path.insert. + # tox installs the sphinx package, no need for sys.path.insert else: newroot = path.join(testroot, path.pardir, 'build') newroot = path.join(newroot, listdir(newroot)[0], 'tests') # always test the sphinx package from build/lib/ - sys.path.insert(0, path.join(newroot, path.pardir)) + sys.path.insert(0, path.abspath(path.join(newroot, path.pardir))) copydir_run_2to3(testroot, newroot) # switch to the converted dir so nose tests the right tests chdir(newroot) diff --git a/tests/test_application.py b/tests/test_application.py index 4baabcec9..87ec42f01 100644 --- a/tests/test_application.py +++ b/tests/test_application.py @@ -5,13 +5,15 @@ Test the Sphinx class. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ from StringIO import StringIO +from docutils import nodes from sphinx.application import ExtensionError +from sphinx.domains import Domain from util import * @@ -40,6 +42,12 @@ def test_events(app): "Callback called when disconnected" +@with_app() +def test_emit_with_multibyte_name_node(app): + node = nodes.section(names=[u'\u65e5\u672c\u8a9e']) + app.emit('my_event', node) + + def test_output(): status, warnings = StringIO(), StringIO() app = TestApp(status=status, warning=warnings) @@ -69,3 +77,23 @@ def test_extensions(): assert warnings.getvalue().startswith("WARNING: extension 'shutil'") finally: app.cleanup() + +def test_domain_override(): + class A(Domain): + name = 'foo' + class B(A): + name = 'foo' + class C(Domain): + name = 'foo' + status, warnings = StringIO(), StringIO() + app = TestApp(status=status, warning=warnings) + try: + # No domain know named foo. + raises_msg(ExtensionError, 'domain foo not yet registered', + app.override_domain, A) + assert app.add_domain(A) is None + assert app.override_domain(B) is None + raises_msg(ExtensionError, 'new domain not a subclass of registered ' + 'foo domain', app.override_domain, C) + finally: + app.cleanup() diff --git a/tests/test_autodoc.py b/tests/test_autodoc.py index 965064c37..fcd064929 100644 --- a/tests/test_autodoc.py +++ b/tests/test_autodoc.py @@ -6,7 +6,7 @@ Test the autodoc extension. This tests mainly the Documenters; the auto directives are tested in a test source file translated by test_build. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ @@ -14,6 +14,7 @@ import sys from StringIO import StringIO from util import * +from nose.tools import with_setup from docutils.statemachine import ViewList @@ -22,8 +23,7 @@ from sphinx.ext.autodoc import AutoDirective, add_documenter, \ def setup_module(): - global app, lid, options, directive - + global app app = TestApp() app.builder.env.app = app app.builder.env.temp_data['docname'] = 'dummy' @@ -31,6 +31,15 @@ def setup_module(): app.connect('autodoc-process-signature', process_signature) app.connect('autodoc-skip-member', skip_member) + +def teardown_module(): + app.cleanup() + + +def setup_test(): + global options, directive + global processed_docstrings, processed_signatures, _warnings + options = Struct( inherited_members = False, undoc_members = False, @@ -54,8 +63,9 @@ def setup_module(): filename_set = set(), ) -def teardown_module(): - app.cleanup() + processed_docstrings = [] + processed_signatures = [] + _warnings = [] _warnings = [] @@ -80,12 +90,15 @@ def process_signature(app, what, name, obj, options, args, retann): def skip_member(app, what, name, obj, skip, options): + if name in ('__special1__', '__special2__'): + return skip if name.startswith('_'): return True if name == 'skipmeth': return True +@with_setup(setup_test) def test_parse_name(): def verify(objtype, name, result): inst = AutoDirective._registry[objtype](directive, name) @@ -127,6 +140,7 @@ def test_parse_name(): del directive.env.temp_data['autodoc:class'] +@with_setup(setup_test) def test_format_signature(): def formatsig(objtype, name, obj, args, retann): inst = AutoDirective._registry[objtype](directive, name) @@ -165,6 +179,20 @@ def test_format_signature(): assert formatsig('class', 'C', C, None, None) == '(a, b=None)' assert formatsig('class', 'C', D, 'a, b', 'X') == '(a, b) -> X' + #__init__ have signature at first line of docstring + class F2: + '''some docstring for F2.''' + def __init__(self, *args, **kw): + ''' + __init__(a1, a2, kw1=True, kw2=False) + + some docstring for __init__. + ''' + class G2(F2, object): + pass + for C in (F2, G2): + assert formatsig('class', 'C', C, None, None) == '(a1, a2, kw1=True, kw2=False)' + # test for methods class H: def foo1(self, b, *c): @@ -182,7 +210,23 @@ def test_format_signature(): # test processing by event handler assert formatsig('method', 'bar', H.foo1, None, None) == '42' + # test functions created via functools.partial + from functools import partial + curried1 = partial(lambda a, b, c: None, 'A') + assert formatsig('function', 'curried1', curried1, None, None) == \ + '(b, c)' + curried2 = partial(lambda a, b, c=42: None, 'A') + assert formatsig('function', 'curried2', curried2, None, None) == \ + '(b, c=42)' + curried3 = partial(lambda a, b, *c: None, 'A') + assert formatsig('function', 'curried3', curried3, None, None) == \ + '(b, *c)' + curried4 = partial(lambda a, b, c=42, *d, **e: None, 'A') + assert formatsig('function', 'curried4', curried4, None, None) == \ + '(b, c=42, *d, **e)' + +@with_setup(setup_test) def test_get_doc(): def getdocl(objtype, obj, encoding=None): inst = AutoDirective._registry[objtype](directive, 'tmp') @@ -251,6 +295,7 @@ def test_get_doc(): '', 'Other', ' lines'] +@with_setup(setup_test) def test_docstring_processing(): def process(objtype, name, obj): inst = AutoDirective._registry[objtype](directive, name) @@ -301,6 +346,8 @@ def test_docstring_processing(): assert process('function', 'h', h) == ['first line', 'third line', ''] app.disconnect(lid) + +@with_setup(setup_test) def test_new_documenter(): class MyDocumenter(ModuleLevelDocumenter): objtype = 'integer' @@ -328,6 +375,40 @@ def test_new_documenter(): assert_result_contains('.. py:data:: integer', 'module', 'test_autodoc') +@with_setup(setup_test, AutoDirective._special_attrgetters.clear) +def test_attrgetter_using(): + def assert_getter_works(objtype, name, obj, attrs=[], **kw): + getattr_spy = [] + def special_getattr(obj, name, *defargs): + if name in attrs: + getattr_spy.append((obj, name)) + return None + return getattr(obj, name, *defargs) + AutoDirective._special_attrgetters[type] = special_getattr + + del getattr_spy[:] + inst = AutoDirective._registry[objtype](directive, name) + inst.generate(**kw) + + hooked_members = [s[1] for s in getattr_spy] + documented_members = [s[1] for s in processed_signatures] + for attr in attrs: + fullname = '.'.join((name, attr)) + assert attr in hooked_members + assert fullname not in documented_members, \ + '%r was not hooked by special_attrgetter function' % fullname + + options.members = ALL + options.inherited_members = False + assert_getter_works('class', 'test_autodoc.Class', Class, + ['meth']) + + options.inherited_members = True + assert_getter_works('class', 'test_autodoc.Class', Class, + ['meth', 'inheritedmeth']) + + +@with_setup(setup_test) def test_generate(): def assert_warns(warn_str, objtype, name, **kw): inst = AutoDirective._registry[objtype](directive, name) @@ -386,10 +467,10 @@ def test_generate(): assert_warns("import for autodocumenting 'foobar'", 'function', 'foobar', more_content=None) # importing - assert_warns("import/find module 'test_foobar'", + assert_warns("failed to import module 'test_foobar'", 'module', 'test_foobar', more_content=None) # attributes missing - assert_warns("import/find function 'util.foobar'", + assert_warns("failed to import function 'foobar' from module 'util'", 'function', 'util.foobar', more_content=None) # test auto and given content mixing @@ -440,6 +521,15 @@ def test_generate(): should.append(('method', 'test_autodoc.Class.inheritedmeth')) assert_processes(should, 'class', 'Class') + # test special members + options.special_members = ['__special1__'] + should.append(('method', 'test_autodoc.Class.__special1__')) + assert_processes(should, 'class', 'Class') + options.special_members = ALL + should.append(('method', 'test_autodoc.Class.__special2__')) + assert_processes(should, 'class', 'Class') + options.special_members = False + options.members = [] # test module flags assert_result_contains('.. py:module:: test_autodoc', @@ -518,6 +608,12 @@ def test_generate(): 'test_autodoc.DocstringSig.meth') assert_result_contains( ' rest of docstring', 'method', 'test_autodoc.DocstringSig.meth') + assert_result_contains( + '.. py:method:: DocstringSig.meth2()', 'method', + 'test_autodoc.DocstringSig.meth2') + assert_result_contains( + ' indented line', 'method', + 'test_autodoc.DocstringSig.meth2') assert_result_contains( '.. py:classmethod:: Class.moore(a, e, f) -> happiness', 'method', 'test_autodoc.Class.moore') @@ -534,6 +630,39 @@ def test_generate(): assert_result_contains( ' :annotation: = None', 'attribute', 'AttCls.a2') + # test explicit members with instance attributes + del directive.env.temp_data['autodoc:class'] + del directive.env.temp_data['autodoc:module'] + directive.env.temp_data['py:module'] = 'test_autodoc' + options.inherited_members = False + options.undoc_members = False + options.members = ALL + assert_processes([ + ('class', 'test_autodoc.InstAttCls'), + ('attribute', 'test_autodoc.InstAttCls.ca1'), + ('attribute', 'test_autodoc.InstAttCls.ca2'), + ('attribute', 'test_autodoc.InstAttCls.ca3'), + ('attribute', 'test_autodoc.InstAttCls.ia1'), + ('attribute', 'test_autodoc.InstAttCls.ia2'), + ], 'class', 'InstAttCls') + del directive.env.temp_data['autodoc:class'] + del directive.env.temp_data['autodoc:module'] + options.members = ['ca1', 'ia1'] + assert_processes([ + ('class', 'test_autodoc.InstAttCls'), + ('attribute', 'test_autodoc.InstAttCls.ca1'), + ('attribute', 'test_autodoc.InstAttCls.ia1'), + ], 'class', 'InstAttCls') + del directive.env.temp_data['autodoc:class'] + del directive.env.temp_data['autodoc:module'] + del directive.env.temp_data['py:module'] + + # test descriptor class documentation + options.members = ['CustomDataDescriptor'] + assert_result_contains('.. py:class:: CustomDataDescriptor(doc)', + 'module', 'test_autodoc') + assert_result_contains(' .. py:method:: CustomDataDescriptor.meth()', + 'module', 'test_autodoc') # --- generate fodder ------------ @@ -559,6 +688,10 @@ class CustomDataDescriptor(object): return self return 42 + def meth(self): + """Function.""" + return "The Answer" + def _funky_classmethod(name, b, c, d, docstring=None): """Generates a classmethod for a class from a template by filling out some arguments.""" @@ -628,6 +761,13 @@ class Class(Base): self.inst_attr_string = None """a documented instance attribute""" + def __special1__(self): + """documented special method""" + + def __special2__(self): + # undocumented special method + pass + class CustomDict(dict): """Docstring.""" @@ -660,6 +800,13 @@ First line of docstring rest of docstring """ + def meth2(self): + """First line, no signature + Second line followed by indentation:: + + indented line + """ + class StrRepr(str): def __repr__(self): return self @@ -667,3 +814,22 @@ class StrRepr(str): class AttCls(object): a1 = StrRepr('hello\nworld') a2 = None + +class InstAttCls(object): + """Class with documented class and instance attributes.""" + + #: Doc comment for class attribute InstAttCls.ca1. + #: It can have multiple lines. + ca1 = 'a' + + ca2 = 'b' #: Doc comment for InstAttCls.ca2. One line only. + + ca3 = 'c' + """Docstring for class attribute InstAttCls.ca3.""" + + def __init__(self): + #: Doc comment for instance attribute InstAttCls.ia1 + self.ia1 = 'd' + + self.ia2 = 'e' + """Docstring for instance attribute InstAttCls.ia2.""" diff --git a/tests/test_autosummary.py b/tests/test_autosummary.py index 048940d0b..dab72c1e5 100644 --- a/tests/test_autosummary.py +++ b/tests/test_autosummary.py @@ -5,7 +5,7 @@ Test the autosummary extension. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/tests/test_build.py b/tests/test_build.py index 5f24f89ac..c2f0b38d1 100644 --- a/tests/test_build.py +++ b/tests/test_build.py @@ -5,11 +5,12 @@ Test all builders that have no special checks. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ from util import * +from textwrap import dedent def teardown_module(): @@ -57,7 +58,35 @@ else: @with_app(buildername='man') def test_man(app): app.builder.build_all() + assert (app.outdir / 'SphinxTests.1').exists() @with_app(buildername='singlehtml', cleanenv=True) def test_singlehtml(app): app.builder.build_all() + +@with_app(buildername='xml') +def test_xml(app): + app.builder.build_all() + +@with_app(buildername='pseudoxml') +def test_pseudoxml(app): + app.builder.build_all() + +@with_app(buildername='html', srcdir='(temp)') +def test_multibyte_path(app): + srcdir = path(app.srcdir) + mb_name = u'\u65e5\u672c\u8a9e' + (srcdir / mb_name).makedirs() + (srcdir / mb_name / (mb_name + '.txt')).write_text(dedent(""" + multi byte file name page + ========================== + """)) + + master_doc = srcdir / 'contents.txt' + master_doc.write_bytes((master_doc.text() + dedent(""" + .. toctree:: + + %(mb_name)s/%(mb_name)s + """ % locals()) + ).encode('utf-8')) + app.builder.build_all() diff --git a/tests/test_build_gettext.py b/tests/test_build_gettext.py index ab68289e3..f6cb4b8e2 100644 --- a/tests/test_build_gettext.py +++ b/tests/test_build_gettext.py @@ -11,6 +11,7 @@ import gettext import os +import re from subprocess import Popen, PIPE from util import * @@ -19,6 +20,7 @@ from util import SkipTest def teardown_module(): (test_root / '_build').rmtree(True) + (test_roots / 'test-intl' / '_build').rmtree(True), @with_app(buildername='gettext') @@ -37,6 +39,14 @@ def test_build(app): assert (app.outdir / 'subdir.pot').isfile() +@with_app(buildername='gettext') +def test_seealso(app): + # regression test for issue #960 + app.builder.build(['markup']) + catalog = (app.outdir / 'markup.pot').text(encoding='utf-8') + assert 'msgid "something, something else, something more"' in catalog + + @with_app(buildername='gettext') def test_gettext(app): app.builder.build(['markup']) @@ -79,3 +89,51 @@ def test_gettext(app): _ = gettext.translation('test_root', app.outdir, languages=['en']).gettext assert _("Testing various markup") == u"Testing various markup" + + +@with_app(buildername='gettext', + srcdir=(test_roots / 'test-intl'), + doctreedir=(test_roots / 'test-intl' / '_build' / 'doctree'), + confoverrides={'gettext_compact': False}) +def test_gettext_index_entries(app): + # regression test for #976 + app.builder.build(['index_entries']) + + _msgid_getter = re.compile(r'msgid "(.*)"').search + def msgid_getter(msgid): + m = _msgid_getter(msgid) + if m: + return m.groups()[0] + return None + + pot = (app.outdir / 'index_entries.pot').text(encoding='utf-8') + msgids = filter(None, map(msgid_getter, pot.splitlines())) + + expected_msgids = [ + "i18n with index entries", + "index target section", + "this is :index:`Newsletter` target paragraph.", + "various index entries", + "That's all.", + "Mailing List", + "Newsletter", + "Recipients List", + "First", + "Second", + "Third", + "Entry", + "See", + "Module", + "Keyword", + "Operator", + "Object", + "Exception", + "Statement", + "Builtin", + ] + for expect in expected_msgids: + assert expect in msgids + msgids.remove(expect) + + # unexpected msgid existent + assert msgids == [] diff --git a/tests/test_build_html.py b/tests/test_build_html.py index a38806a86..abd60bbb5 100644 --- a/tests/test_build_html.py +++ b/tests/test_build_html.py @@ -5,7 +5,7 @@ Test the HTML builder and check output against XPath. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ @@ -44,7 +44,7 @@ reading included file u'.*?wrongenc.inc' seems to be wrong, try giving an \ %(root)s/includes.txt:4: WARNING: download file not readable: .*?nonexisting.png %(root)s/objects.txt:\\d*: WARNING: using old C markup; please migrate to \ new-style markup \(e.g. c:function instead of cfunction\), see \ -http://sphinx.pocoo.org/domains.html +http://sphinx-doc.org/domains.html """ HTML_WARNINGS = ENV_WARNINGS + """\ @@ -319,7 +319,8 @@ def check_static_entries(outdir): def test_html(app): app.builder.build_all() html_warnings = html_warnfile.getvalue().replace(os.sep, '/') - html_warnings_exp = HTML_WARNINGS % {'root': re.escape(app.srcdir)} + html_warnings_exp = HTML_WARNINGS % { + 'root': re.escape(app.srcdir.replace(os.sep, '/'))} assert re.match(html_warnings_exp + '$', html_warnings), \ 'Warnings don\'t match:\n' + \ '--- Expected (regex):\n' + html_warnings_exp + \ @@ -328,7 +329,7 @@ def test_html(app): for fname, paths in HTML_XPATH.iteritems(): parser = NslessParser() parser.entity.update(htmlentitydefs.entitydefs) - fp = open(os.path.join(app.outdir, fname)) + fp = open(os.path.join(app.outdir, fname), 'rb') try: etree = ET.parse(fp, parser) finally: diff --git a/tests/test_build_latex.py b/tests/test_build_latex.py index 4e1e9f70c..721b3a2dd 100644 --- a/tests/test_build_latex.py +++ b/tests/test_build_latex.py @@ -5,7 +5,7 @@ Test the build process with LaTeX builder with the test root. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ @@ -42,7 +42,8 @@ def test_latex(app): LaTeXTranslator.ignore_missing_images = True app.builder.build_all() latex_warnings = latex_warnfile.getvalue().replace(os.sep, '/') - latex_warnings_exp = LATEX_WARNINGS % {'root': re.escape(app.srcdir)} + latex_warnings_exp = LATEX_WARNINGS % { + 'root': re.escape(app.srcdir.replace(os.sep, '/'))} assert re.match(latex_warnings_exp + '$', latex_warnings), \ 'Warnings don\'t match:\n' + \ '--- Expected (regex):\n' + latex_warnings_exp + \ diff --git a/tests/test_build_texinfo.py b/tests/test_build_texinfo.py index c626c976b..37ad0582a 100644 --- a/tests/test_build_texinfo.py +++ b/tests/test_build_texinfo.py @@ -5,7 +5,7 @@ Test the build process with Texinfo builder with the test root. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ @@ -41,7 +41,8 @@ def test_texinfo(app): TexinfoTranslator.ignore_missing_images = True app.builder.build_all() texinfo_warnings = texinfo_warnfile.getvalue().replace(os.sep, '/') - texinfo_warnings_exp = TEXINFO_WARNINGS % {'root': re.escape(app.srcdir)} + texinfo_warnings_exp = TEXINFO_WARNINGS % { + 'root': re.escape(app.srcdir.replace(os.sep, '/'))} assert re.match(texinfo_warnings_exp + '$', texinfo_warnings), \ 'Warnings don\'t match:\n' + \ '--- Expected (regex):\n' + texinfo_warnings_exp + \ diff --git a/tests/test_build_text.py b/tests/test_build_text.py new file mode 100644 index 000000000..79edc6230 --- /dev/null +++ b/tests/test_build_text.py @@ -0,0 +1,86 @@ +# -*- coding: utf-8 -*- +""" + test_build_text + ~~~~~~~~~~~~~~~ + + Test the build process with Text builder with the test root. + + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" + +from textwrap import dedent + +from docutils.utils import column_width +from sphinx.writers.text import MAXWIDTH + +from util import * + + +def with_text_app(*args, **kw): + default_kw = { + 'buildername': 'text', + 'srcdir': '(empty)', + 'confoverrides': { + 'project': 'text', + 'master_doc': 'contents', + }, + } + default_kw.update(kw) + return with_app(*args, **default_kw) + + +@with_text_app() +def test_multibyte_title_line(app): + title = u'\u65e5\u672c\u8a9e' + underline = u'=' * column_width(title) + content = u'\n'.join((title, underline, u'')) + + (app.srcdir / 'contents.rst').write_text(content, encoding='utf-8') + app.builder.build_all() + result = (app.outdir / 'contents.txt').text(encoding='utf-8') + + expect_underline = underline.replace('=', '*') + result_underline = result.splitlines()[2].strip() + assert expect_underline == result_underline + + +@with_text_app() +def test_multibyte_table(app): + text = u'\u65e5\u672c\u8a9e' + contents = (u"\n.. list-table::" + "\n" + "\n - - spam" + "\n - egg" + "\n" + "\n - - %(text)s" + "\n - %(text)s" + "\n" % locals()) + + (app.srcdir / 'contents.rst').write_text(contents, encoding='utf-8') + app.builder.build_all() + result = (app.outdir / 'contents.txt').text(encoding='utf-8') + + lines = [line.strip() for line in result.splitlines() if line.strip()] + line_widths = [column_width(line) for line in lines] + assert len(set(line_widths)) == 1 # same widths + + +@with_text_app() +def test_multibyte_maxwidth(app): + sb_text = u'abc' #length=3 + mb_text = u'\u65e5\u672c\u8a9e' #length=3 + + sb_line = ' '.join([sb_text] * int(MAXWIDTH / 3)) + mb_line = ' '.join([mb_text] * int(MAXWIDTH / 3)) + mix_line = ' '.join([sb_text, mb_text] * int(MAXWIDTH / 6)) + + contents = u'\n\n'.join((sb_line, mb_line, mix_line)) + + (app.srcdir / 'contents.rst').write_text(contents, encoding='utf-8') + app.builder.build_all() + result = (app.outdir / 'contents.txt').text(encoding='utf-8') + + lines = [line.strip() for line in result.splitlines() if line.strip()] + line_widths = [column_width(line) for line in lines] + assert max(line_widths) < MAXWIDTH diff --git a/tests/test_config.py b/tests/test_config.py index b07a71bf1..84a3b4b77 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -6,7 +6,7 @@ Test the sphinx.config.Config class and its handling in the Application class. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ import sys @@ -16,6 +16,7 @@ from util import * import sphinx from sphinx.config import Config from sphinx.errors import ExtensionError, ConfigError, VersionRequirementError +from sphinx.util.pycompat import b @with_app(confoverrides={'master_doc': 'master', 'nonexisting_value': 'True', @@ -113,3 +114,14 @@ def test_errors_warnings(dir): def test_needs_sphinx(): raises(VersionRequirementError, TestApp, confoverrides={'needs_sphinx': '9.9'}) + + +@with_tempdir +def test_config_eol(tmpdir): + # test config file's eol patterns: LF, CRLF + configfile = tmpdir / 'conf.py' + for eol in ('\n', '\r\n'): + configfile.write_bytes(b('project = "spam"' + eol)) + cfg = Config(tmpdir, 'conf.py', {}, None) + cfg.init_values() + assert cfg.project == u'spam' diff --git a/tests/test_coverage.py b/tests/test_coverage.py index c554c52c7..88c66140f 100644 --- a/tests/test_coverage.py +++ b/tests/test_coverage.py @@ -5,7 +5,7 @@ Test the coverage builder. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/tests/test_cpp_domain.py b/tests/test_cpp_domain.py index 3ab8ece4c..db2589d50 100644 --- a/tests/test_cpp_domain.py +++ b/tests/test_cpp_domain.py @@ -5,13 +5,13 @@ Tests the C++ Domain - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ from util import * -from sphinx.domains.cpp import DefinitionParser +from sphinx.domains.cpp import DefinitionParser, DefinitionError def parse(name, string): @@ -43,6 +43,15 @@ def test_type_definitions(): x = 'int printf(const char* fmt, ...)' assert unicode(parse('function', x)) == x + x = 'int foo(const unsigned int j)' + assert unicode(parse('function', x)) == x + + x = 'int foo(const unsigned int const j)' + assert unicode(parse('function', x)) == x + + x = 'int foo(const int* const ptr)' + assert unicode(parse('function', x)) == x + x = 'std::vector> module::blah' assert unicode(parse('type_object', x)) == x @@ -60,6 +69,9 @@ def test_type_definitions(): x = 'constexpr int get_value()' assert unicode(parse('function', x)) == x + x = 'static constexpr int get_value()' + assert unicode(parse('function', x)) == x + x = 'int get_value() const noexcept' assert unicode(parse('function', x)) == x @@ -73,6 +85,21 @@ def test_type_definitions(): x = 'module::myclass foo[n]' assert unicode(parse('member_object', x)) == x + x = 'int foo(Foo f=Foo(double(), std::make_pair(int(2), double(3.4))))' + assert unicode(parse('function', x)) == x + + x = 'int foo(A a=x(a))' + assert unicode(parse('function', x)) == x + + x = 'int foo(B b=x(a)' + raises(DefinitionError, parse, 'function', x) + + x = 'int foo)C c=x(a))' + raises(DefinitionError, parse, 'function', x) + + x = 'int foo(D d=x(a' + raises(DefinitionError, parse, 'function', x) + def test_bases(): x = 'A' diff --git a/tests/test_doctest.py b/tests/test_doctest.py index 577fcb00e..4934e716b 100644 --- a/tests/test_doctest.py +++ b/tests/test_doctest.py @@ -5,7 +5,7 @@ Test the doctest extension. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/tests/test_env.py b/tests/test_env.py index e62db33bd..12e0719da 100644 --- a/tests/test_env.py +++ b/tests/test_env.py @@ -5,7 +5,7 @@ Test the BuildEnvironment class. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ import sys @@ -54,6 +54,7 @@ def test_images(): tree = env.get_doctree('images') app._warning.reset() htmlbuilder = StandaloneHTMLBuilder(app) + htmlbuilder.imgpath = 'dummy' htmlbuilder.post_process_images(tree) image_uri_message = "no matching candidate for image URI u'foo.*'" if sys.version_info >= (3, 0): diff --git a/tests/test_footnote.py b/tests/test_footnote.py new file mode 100644 index 000000000..3a3d59670 --- /dev/null +++ b/tests/test_footnote.py @@ -0,0 +1,37 @@ +# -*- coding: utf-8 -*- +""" + test_footnote + ~~~~~~~~~~~~~ + + Test for footnote and citation. + + :copyright: Copyright 2010 by the Sphinx team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" + +import re + +from util import * + + +def teardown_module(): + (test_root / '_build').rmtree(True) + + +@with_app(buildername='html') +def test_html(app): + app.builder.build(['footnote']) + result = (app.outdir / 'footnote.html').text(encoding='utf-8') + expects = [ + '[1]', + '[2]', + '[3]', + '[bar]', + '[1]', + '[2]', + '[3]', + '[bar]', + ] + for expect in expects: + matches = re.findall(re.escape(expect), result) + assert len(matches) == 1 diff --git a/tests/test_highlighting.py b/tests/test_highlighting.py index 949552c1e..b392193d6 100644 --- a/tests/test_highlighting.py +++ b/tests/test_highlighting.py @@ -5,7 +5,7 @@ Test the Pygments highlighting bridge. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/tests/test_i18n.py b/tests/test_i18n.py index 930108e95..210243e79 100644 --- a/tests/test_i18n.py +++ b/tests/test_i18n.py @@ -5,7 +5,7 @@ Test locale features. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/tests/test_intersphinx.py b/tests/test_intersphinx.py index 55320eaec..0171ae035 100644 --- a/tests/test_intersphinx.py +++ b/tests/test_intersphinx.py @@ -5,7 +5,7 @@ Test the intersphinx extension. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ diff --git a/tests/test_intl.py b/tests/test_intl.py index d1e28002f..4dec84646 100644 --- a/tests/test_intl.py +++ b/tests/test_intl.py @@ -11,43 +11,68 @@ """ from subprocess import Popen, PIPE +import re +import os +from StringIO import StringIO + +from sphinx.util.pycompat import relpath from util import * from util import SkipTest +warnfile = StringIO() +root = test_roots / 'test-intl' +doctreedir = root / '_build' / 'doctree' + + +def with_intl_app(*args, **kw): + default_kw = { + 'srcdir': root, + 'doctreedir': doctreedir, + 'confoverrides': { + 'language': 'xx', 'locale_dirs': ['.'], + 'gettext_compact': False, + }, + } + default_kw.update(kw) + return with_app(*args, **default_kw) + + def setup_module(): - (test_root / 'xx' / 'LC_MESSAGES').makedirs() + # Delete remnants left over after failed build + (root / 'xx').rmtree(True) + (root / 'xx' / 'LC_MESSAGES').makedirs() # Compile all required catalogs into binary format (*.mo). - for catalog in 'bom', 'subdir': - try: - p = Popen(['msgfmt', test_root / '%s.po' % catalog, '-o', - test_root / 'xx' / 'LC_MESSAGES' / '%s.mo' % catalog], - stdout=PIPE, stderr=PIPE) - except OSError: - # The test will fail the second time it's run if we don't - # tear down here. Not sure if there's a more idiomatic way - # of ensuring that teardown gets run in the event of an - # exception from the setup function. - teardown_module() - raise SkipTest # most likely msgfmt was not found - else: - stdout, stderr = p.communicate() - if p.returncode != 0: - print stdout - print stderr - assert False, 'msgfmt exited with return code %s' % p.returncode - assert (test_root / 'xx' / 'LC_MESSAGES' / ('%s.mo' % catalog) - ).isfile(), 'msgfmt failed' + for dirpath, dirs, files in os.walk(root): + dirpath = path(dirpath) + for f in [f for f in files if f.endswith('.po')]: + po = dirpath / f + mo = root / 'xx' / 'LC_MESSAGES' / ( + relpath(po[:-3], root) + '.mo') + if not mo.parent.exists(): + mo.parent.makedirs() + try: + p = Popen(['msgfmt', po, '-o', mo], + stdout=PIPE, stderr=PIPE) + except OSError: + raise SkipTest # most likely msgfmt was not found + else: + stdout, stderr = p.communicate() + if p.returncode != 0: + print stdout + print stderr + assert False, \ + 'msgfmt exited with return code %s' % p.returncode + assert mo.isfile(), 'msgfmt failed' def teardown_module(): - (test_root / '_build').rmtree(True) - (test_root / 'xx').rmtree(True) + (root / '_build').rmtree(True) + (root / 'xx').rmtree(True) -@with_app(buildername='text', - confoverrides={'language': 'xx', 'locale_dirs': ['.']}) +@with_intl_app(buildername='text') def test_simple(app): app.builder.build(['bom']) result = (app.outdir / 'bom.txt').text(encoding='utf-8') @@ -57,9 +82,308 @@ def test_simple(app): assert result == expect -@with_app(buildername='text', - confoverrides={'language': 'xx', 'locale_dirs': ['.']}) +@with_intl_app(buildername='text') def test_subdir(app): - app.builder.build(['subdir/includes']) - result = (app.outdir / 'subdir' / 'includes.txt').text(encoding='utf-8') - assert result.startswith(u"\ntranslation\n***********\n\n") + app.builder.build(['subdir/contents']) + result = (app.outdir / 'subdir' / 'contents.txt').text(encoding='utf-8') + assert result.startswith(u"\nsubdir contents\n***************\n") + + +@with_intl_app(buildername='text', warning=warnfile) +def test_i18n_warnings_in_translation(app): + app.builddir.rmtree(True) + app.builder.build(['warnings']) + result = (app.outdir / 'warnings.txt').text(encoding='utf-8') + expect = (u"\nI18N WITH REST WARNINGS" + u"\n***********************\n" + u"\nLINE OF >>``<[100]', + '[1]', + '[ref]', + '[1]', + '[ref]', + '[100]', + ] + for expect in expects: + matches = re.findall(re.escape(expect), result) + assert len(matches) == 1 + + +@with_intl_app(buildername='text', warning=warnfile, cleanenv=True) +def test_i18n_warn_for_number_of_references_inconsistency(app): + app.builddir.rmtree(True) + app.builder.build(['refs_inconsistency']) + result = (app.outdir / 'refs_inconsistency.txt').text(encoding='utf-8') + expect = (u"\nI18N WITH REFS INCONSISTENCY" + u"\n****************************\n" + u"\n* FOR FOOTNOTE [ref2].\n" + u"\n* reference FOR reference.\n" + u"\n* ORPHAN REFERENCE: I18N WITH REFS INCONSISTENCY.\n" + u"\n[1] THIS IS A AUTO NUMBERED FOOTNOTE.\n" + u"\n[ref2] THIS IS A NAMED FOOTNOTE.\n" + u"\n[100] THIS IS A NUMBERED FOOTNOTE.\n") + assert result == expect + + warnings = warnfile.getvalue().replace(os.sep, '/') + warning_fmt = u'.*/refs_inconsistency.txt:\\d+: ' \ + u'WARNING: inconsistent %s in translated message\n' + expected_warning_expr = ( + warning_fmt % 'footnote references' + + warning_fmt % 'references' + + warning_fmt % 'references') + assert re.search(expected_warning_expr, warnings) + + +@with_intl_app(buildername='html', cleanenv=True) +def test_i18n_link_to_undefined_reference(app): + app.builder.build(['refs_inconsistency']) + result = (app.outdir / 'refs_inconsistency.html').text(encoding='utf-8') + + expected_expr = ('reference') + assert len(re.findall(expected_expr, result)) == 2 + + expected_expr = ('reference') + assert len(re.findall(expected_expr, result)) == 0 + + expected_expr = ('I18N WITH ' + 'REFS INCONSISTENCY') + assert len(re.findall(expected_expr, result)) == 1 + + +@with_intl_app(buildername='html', cleanenv=True) +def test_i18n_keep_external_links(app): + """regression test for #1044""" + app.builder.build(['external_links']) + result = (app.outdir / 'external_links.html').text(encoding='utf-8') + + # external link check + expect_line = (u'
      • EXTERNAL LINK TO Python.
      • ') + matched = re.search('^
      • EXTERNAL LINK TO .*$', result, re.M) + matched_line = '' + if matched: + matched_line = matched.group() + assert expect_line == matched_line + + # internal link check + expect_line = (u'
      • EXTERNAL ' + u'LINKS IS INTERNAL LINK.
      • ') + matched = re.search('^
      • $', result, re.M) + matched_line = '' + if matched: + matched_line = matched.group() + assert expect_line == matched_line + + # inline link check + expect_line = (u'
      • INLINE LINK BY SPHINX.
      • ') + matched = re.search('^
      • INLINE LINK BY .*$', result, re.M) + matched_line = '' + if matched: + matched_line = matched.group() + assert expect_line == matched_line + + # unnamed link check + expect_line = (u'
      • UNNAMED LINK.
      • ') + matched = re.search('^
      • UNNAMED .*$', result, re.M) + matched_line = '' + if matched: + matched_line = matched.group() + assert expect_line == matched_line + + +@with_intl_app(buildername='text', warning=warnfile, cleanenv=True) +def test_i18n_literalblock_warning(app): + app.builddir.rmtree(True) #for warnings acceleration + app.builder.build(['literalblock']) + result = (app.outdir / 'literalblock.txt').text(encoding='utf-8') + expect = (u"\nI18N WITH LITERAL BLOCK" + u"\n***********************\n" + u"\nCORRECT LITERAL BLOCK:\n" + u"\n this is" + u"\n literal block\n" + u"\nMISSING LITERAL BLOCK:\n" + u"\n=0.10.0 + {[testenv]deps} [testenv:pypy] deps= - nose simplejson - -[testenv:du05] -deps= - nose - docutils==0.5 - -[testenv:du06] -deps= - nose - docutils==0.6 + {[testenv]deps} [testenv:du07] deps= - nose docutils==0.7 + {[testenv]deps} [testenv:du08] deps= - nose docutils==0.8.1 + {[testenv]deps} + +[testenv:du09] +deps= + docutils==0.9.1 + {[testenv]deps} + +[testenv:du10] +deps= + docutils==0.10.0 + {[testenv]deps} diff --git a/utils/check_sources.py b/utils/check_sources.py index 6b030d5d8..5512420a9 100755 --- a/utils/check_sources.py +++ b/utils/check_sources.py @@ -7,7 +7,7 @@ Make sure each Python file has a correct file header including copyright and license information. - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """