diff --git a/CHANGES b/CHANGES index 2415a3822..12a395039 100644 --- a/CHANGES +++ b/CHANGES @@ -123,12 +123,14 @@ Bugs fixed * #1147: Don't emit a sidebar search box in the "singlehtml" builder. * PR#211: When checking for existence of the :confval:`html_logo` file, check the full relative path and not the basename. -* PR#212: Fix traceback with autodoc and ``__init__`` methods without docstring. +* #1357: Option names documented by :rst:dir:`option` are now again allowed to + not start with a dash or slash, and referencing them will work correctly. Documentation ------------- * #1325: Added a "Intersphinx" tutorial section. (:file:`doc/tutorial.rst`) +* Extended the :ref:`documentation about building extensions `. Release 1.2 (released Dec 10, 2013) diff --git a/doc/domains.rst b/doc/domains.rst index 6c3c43594..483052a91 100644 --- a/doc/domains.rst +++ b/doc/domains.rst @@ -633,16 +633,20 @@ There is a set of directives allowing documenting command-line programs: .. rst:directive:: .. option:: name args, name args, ... - Describes a command line option or switch. Option argument names should be - enclosed in angle brackets. Example:: + Describes a command line argument or switch. Option argument names should be + enclosed in angle brackets. Examples:: + + .. option:: dest_dir + + Destination directory. .. option:: -m , --module Run a module as a script. - The directive will create a cross-reference target named after the *first* - option, referencable by :rst:role:`option` (in the example case, you'd use - something like ``:option:`-m```). + The directive will create cross-reference targets for the given options, + referencable by :rst:role:`option` (in the example case, you'd use something + like ``:option:`dest_dir```, ``:option:`-m```, or ``:option:`--module```). .. rst:directive:: .. envvar:: name diff --git a/doc/extdev/appapi.rst b/doc/extdev/appapi.rst index eca191bbd..88fd43404 100644 --- a/doc/extdev/appapi.rst +++ b/doc/extdev/appapi.rst @@ -359,6 +359,12 @@ Producing messages / logging The application object also provides support for emitting leveled messages. +.. note:: + + There is no "error" call: in Sphinx, errors are defined as things that stop + the build; just raise an exception (:exc:`sphinx.errors.SphinxError` or a + custom subclass) to do that. + .. automethod:: Sphinx.warn .. automethod:: Sphinx.info @@ -535,3 +541,47 @@ The template bridge .. autoclass:: TemplateBridge :members: + + +.. _exceptions: + +Exceptions +---------- + +.. module:: sphinx.errors + +.. exception:: SphinxError + + This is the base class for "nice" exceptions. When such an exception is + raised, Sphinx will abort the build and present the exception category and + message to the user. + + Extensions are encouraged to derive from this exception for their custom + errors. + + Exceptions *not* derived from :exc:`SphinxError` are treated as unexpected + and shown to the user with a part of the traceback (and the full traceback + saved in a temporary file). + + .. attribute:: category + + Description of the exception "category", used in converting the exception + to a string ("category: message"). Should be set accordingly in + subclasses. + +.. exception:: ConfigError + + Used for erroneous values or nonsensical combinations of configuration + values. + +.. exception:: ExtensionError + + Used for errors in setting up extensions. + +.. exception:: ThemeError + + Used for errors to do with themes. + +.. exception:: VersionRequirementError + + Raised when the docs require a higher Sphinx version than the current one. diff --git a/doc/extdev/markupapi.rst b/doc/extdev/markupapi.rst index 8f6c29b1f..3c09687eb 100644 --- a/doc/extdev/markupapi.rst +++ b/doc/extdev/markupapi.rst @@ -1,6 +1,9 @@ Docutils markup API =================== +This section describes the API for adding ReST markup elements (roles and +directives). + Roles ----- @@ -8,4 +11,129 @@ Roles Directives ---------- -TODO. +Directives are handled by classes derived from +``docutils.parsers.rst.Directive``. They have to be registered by an extension +using :meth:`.Sphinx.add_directive` or :meth:`.Sphinx.add_directive_to_domain`. + +.. module:: docutils.parsers.rst + +.. class:: Directive + + The markup syntax of the new directive is determined by the follow five class + attributes: + + .. autoattribute:: required_arguments + .. autoattribute:: optional_arguments + .. autoattribute:: final_argument_whitespace + .. autoattribute:: option_spec + + Option validator functions take a single parameter, the option argument + (or ``None`` if not given), and should validate it or convert it to the + proper form. They raise :exc:`ValueError` or :exc:`TypeError` to indicate + failure. + + There are several predefined and possibly useful validators in the + :mod:`docutils.parsers.rst.directives` module. + + .. autoattribute:: has_content + + New directives must implement the :meth:`run` method: + + .. method:: run() + + This method must process the directive arguments, options and content, and + return a list of Docutils/Sphinx nodes that will be inserted into the + document tree at the point where the directive was encountered. + + Instance attributes that are always set on the directive are: + + .. attribute:: name + + The directive name (useful when registering the same directive class under + multiple names). + + .. attribute:: arguments + + The arguments given to the directive, as a list. + + .. attribute:: options + + The options given to the directive, as a dictionary mapping option names + to validated/converted values. + + .. attribute:: content + + The directive content, if given, as a :class:`.ViewList`. + + .. attribute:: lineno + + The absolute line number on which the directive appeared. This is not + always a useful value; use :attr:`srcline` instead. + + .. attribute:: src + + The source file of the directive. + + .. attribute:: srcline + + The line number in the source file on which the directive appeared. + + .. attribute:: content_offset + + Internal offset of the directive content. Used when calling + ``nested_parse`` (see below). + + .. attribute:: block_text + + The string containing the entire directive. + + .. attribute:: state + state_machine + + The state and state machine which controls the parsing. Used for + ``nested_parse``. + + +ViewLists +^^^^^^^^^ + +Docutils represents document source lines in a class +``docutils.statemachine.ViewList``. This is a list with extended functionality +-- for one, slicing creates views of the original list, and also the list +contains information about the source line numbers. + +The :attr:`Directive.content` attribute is a ViewList. If you generate content +to be parsed as ReST, you have to create a ViewList yourself. Important for +content generation are the following points: + +* The constructor takes a list of strings (lines) and a source (document) name. + +* The ``.append()`` method takes a line and a source name as well. + + +Parsing directive content as ReST +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Many directives will contain more markup that must be parsed. To do this, use +one of the following APIs from the :meth:`Directive.run` method: + +* ``self.state.nested_parse`` +* :func:`sphinx.util.nodes.nested_parse_with_titles` -- this allows titles in + the parsed content. + +Both APIs parse the content into a given node. They are used like this:: + + node = docutils.nodes.paragraph() + # either + nested_parse_with_titles(self.state, self.result, node) + # or + self.state.nested_parse(self.result, 0, node) + +If you don't need the wrapping node, you can use any concrete node type and +return ``node.children`` from the Directive. + + +.. seealso:: + + `Creating directives `_ + HOWTO of the Docutils documentation diff --git a/doc/extdev/tutorial.rst b/doc/extdev/tutorial.rst index 382641904..a03d6e08b 100644 --- a/doc/extdev/tutorial.rst +++ b/doc/extdev/tutorial.rst @@ -225,10 +225,10 @@ The Directive Classes --------------------- A directive class is a class deriving usually from -``docutils.parsers.rst.Directive``. The directive interface is covered in -detail in the `docutils documentation`_; the important thing is that the class -has attributes that configure the allowed markup and a method ``run`` that -returns a list of nodes. +:class:`docutils.parsers.rst.Directive`. The directive interface is also +covered in detail in the `docutils documentation`_; the important thing is that +the class has attributes that configure the allowed markup and a method ``run`` +that returns a list of nodes. The ``todolist`` directive is quite simple:: diff --git a/doc/markup/code.rst b/doc/markup/code.rst index e9f8f1da4..ab387c6db 100644 --- a/doc/markup/code.rst +++ b/doc/markup/code.rst @@ -60,7 +60,8 @@ installed) and handled in a smart way: certain well-recognizable languages) * ``rest`` * ``c`` - * ... and any other lexer name that Pygments supports. + * ... and any other `lexer alias that Pygments supports + `_. * If highlighting with the selected language fails (i.e. Pygments emits an "Error" token), the block is not highlighted in any way. diff --git a/setup.py b/setup.py index 53a4c04b2..21f6709e2 100644 --- a/setup.py +++ b/setup.py @@ -39,9 +39,6 @@ Among its features are the following: * Various extensions are available, e.g. for automatic testing of snippets and inclusion of appropriately formatted docstrings * Setuptools integration - -A development egg can be found `here -`_. ''' if sys.version_info < (2, 6) or (3, 0) <= sys.version_info < (3, 2): diff --git a/sphinx/application.py b/sphinx/application.py index 89d6f6232..46caa3265 100644 --- a/sphinx/application.py +++ b/sphinx/application.py @@ -244,9 +244,11 @@ class Sphinx(object): *prefix* usually should not be changed. - .. note:: For warnings emitted during parsing, you should use - :meth:`.BuildEnvironment.warn` since that will collect all - warnings during parsing for later output. + .. note:: + + For warnings emitted during parsing, you should use + :meth:`.BuildEnvironment.warn` since that will collect all + warnings during parsing for later output. """ if isinstance(location, tuple): docname, lineno = location diff --git a/sphinx/cmdline.py b/sphinx/cmdline.py index a1c27c79c..3af5863f7 100644 --- a/sphinx/cmdline.py +++ b/sphinx/cmdline.py @@ -289,9 +289,7 @@ def main(argv): print('Please also report this if it was a user error, so ' 'that a better error message can be provided next time.', file=error) - print('Either send bugs to the mailing list at ' - ',\n' - 'or report them in the tracker at ' - '. Thanks!', + print('A bug report can be filed in the tracker at ' + '. Thanks!', file=error) return 1 diff --git a/sphinx/domains/std.py b/sphinx/domains/std.py index 49dc61b48..423fcb957 100644 --- a/sphinx/domains/std.py +++ b/sphinx/domains/std.py @@ -27,7 +27,7 @@ from sphinx.util.compat import Directive # RE for option descriptions -option_desc_re = re.compile(r'((?:/|-|--)[-_a-zA-Z0-9]+)(\s*.*)') +option_desc_re = re.compile(r'((?:/|-|--)?[-_a-zA-Z0-9]+)(\s*.*)') class GenericObject(ObjectDescription): @@ -143,7 +143,7 @@ class Cmdoption(ObjectDescription): self.env.warn( self.env.docname, 'Malformed option description %r, should ' - 'look like "-opt args", "--opt args" or ' + 'look like "opt", "-opt args", "--opt args" or ' '"/opt args"' % potential_option, self.lineno) continue optname, args = m.groups() @@ -153,25 +153,33 @@ class Cmdoption(ObjectDescription): signode += addnodes.desc_addname(args, args) if not count: firstname = optname + signode['allnames'] = [optname] + else: + signode['allnames'].append(optname) count += 1 if not firstname: raise ValueError return firstname - def add_target_and_index(self, name, sig, signode): - targetname = name.replace('/', '-') + def add_target_and_index(self, firstname, sig, signode): currprogram = self.env.temp_data.get('std:program') - if currprogram: - targetname = '-' + currprogram + targetname - targetname = 'cmdoption' + targetname - signode['ids'].append(targetname) - self.state.document.note_explicit_target(signode) - self.indexnode['entries'].append( - ('pair', _('%scommand line option; %s') % - ((currprogram and currprogram + ' ' or ''), sig), - targetname, '')) - self.env.domaindata['std']['progoptions'][currprogram, name] = \ - self.env.docname, targetname + for optname in signode.get('allnames', []): + targetname = optname.replace('/', '-') + if not targetname.startswith('-'): + targetname = '-arg-' + targetname + if currprogram: + targetname = '-' + currprogram + targetname + targetname = 'cmdoption' + targetname + signode['ids'].append(targetname) + self.state.document.note_explicit_target(signode) + self.env.domaindata['std']['progoptions'][currprogram, optname] = \ + self.env.docname, targetname + # create only one index entry for the whole option + if optname == firstname: + self.indexnode['entries'].append( + ('pair', _('%scommand line option; %s') % + ((currprogram and currprogram + ' ' or ''), sig), + targetname, '')) class Program(Directive): diff --git a/sphinx/setup_command.py b/sphinx/setup_command.py index 02449137e..88cbc5a0d 100644 --- a/sphinx/setup_command.py +++ b/sphinx/setup_command.py @@ -18,6 +18,7 @@ import os import types from StringIO import StringIO from distutils.cmd import Command +from distutils.errors import DistutilsOptionError from sphinx.application import Sphinx from sphinx.util.console import darkred, nocolor, color_terminal diff --git a/sphinx/writers/html.py b/sphinx/writers/html.py index c9104cebf..431385cb9 100644 --- a/sphinx/writers/html.py +++ b/sphinx/writers/html.py @@ -79,6 +79,7 @@ class HTMLTranslator(BaseTranslator): self.permalink_text = self.encode(self.permalink_text) self.secnumber_suffix = builder.config.html_secnumber_suffix self.param_separator = '' + self.optional_param_level = 0 self._table_row_index = 0 def visit_start_of_file(self, node):