mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
#14: allow distinct programs for cmdoption directive.
This commit is contained in:
parent
7b62fc8f2d
commit
fb26a2a5fc
@ -17,7 +17,7 @@ typical module section might start like this::
|
||||
.. moduleauthor:: John Idle <john@python.invalid>
|
||||
|
||||
|
||||
The directives you can use for module are:
|
||||
The directives you can use for module declarations are:
|
||||
|
||||
.. directive:: .. module:: name
|
||||
|
||||
@ -67,8 +67,8 @@ The directives you can use for module are:
|
||||
|
||||
.. _desc-units:
|
||||
|
||||
Description units
|
||||
-----------------
|
||||
Object description units
|
||||
------------------------
|
||||
|
||||
There are a number of directives used to describe specific features provided by
|
||||
modules. Each directive requires one or more signatures to provide basic
|
||||
@ -204,39 +204,6 @@ The directives are:
|
||||
Like :dir:`method`, but indicates that the method is a static method.
|
||||
|
||||
.. versionadded:: 0.4
|
||||
|
||||
.. directive:: .. cmdoption:: name args, name args, ...
|
||||
|
||||
Describes a command line option or switch. Option argument names should be
|
||||
enclosed in angle brackets. Example::
|
||||
|
||||
.. cmdoption:: -m <module>, --module <module>
|
||||
|
||||
Run a module as a script.
|
||||
|
||||
The directive will create a cross-reference target named after the *first*
|
||||
option, referencable by :role:`option` (in the example case, you'd use
|
||||
something like ``:option:`-m```).
|
||||
|
||||
.. directive:: .. envvar:: name
|
||||
|
||||
Describes an environment variable that the documented code uses or defines.
|
||||
|
||||
|
||||
There is also a generic version of these directives:
|
||||
|
||||
.. directive:: .. describe:: text
|
||||
|
||||
This directive produces the same formatting as the specific ones explained
|
||||
above but does not create index entries or cross-referencing targets. It is
|
||||
used, for example, to describe the directives in this document. Example::
|
||||
|
||||
.. describe:: opcode
|
||||
|
||||
Describes a Python bytecode instruction.
|
||||
|
||||
Extensions may add more directives like that, using the
|
||||
:func:`~sphinx.application.Sphinx.add_description_unit` method.
|
||||
|
||||
|
||||
.. _signatures:
|
||||
@ -308,3 +275,77 @@ This will render like this:
|
||||
:param limit: maximum number of stack frames to show
|
||||
:type limit: integer or None
|
||||
:rtype: list of strings
|
||||
|
||||
|
||||
Command-line program markup
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
There is a set of directives allowing documenting command-line programs:
|
||||
|
||||
.. directive:: .. cmdoption:: name args, name args, ...
|
||||
|
||||
Describes a command line option or switch. Option argument names should be
|
||||
enclosed in angle brackets. Example::
|
||||
|
||||
.. cmdoption:: -m <module>, --module <module>
|
||||
|
||||
Run a module as a script.
|
||||
|
||||
The directive will create a cross-reference target named after the *first*
|
||||
option, referencable by :role:`option` (in the example case, you'd use
|
||||
something like ``:option:`-m```).
|
||||
|
||||
.. directive:: .. envvar:: name
|
||||
|
||||
Describes an environment variable that the documented code or program uses or
|
||||
defines.
|
||||
|
||||
|
||||
.. directive:: .. program:: name
|
||||
|
||||
Like :dir:`currentmodule`, this directive produces no output. Instead, it
|
||||
serves to notify Sphinx that all following :dir:`cmdoption` directives
|
||||
document options for the program called *name*.
|
||||
|
||||
If you use :dir:`program`, you have to qualify the references in your
|
||||
:role:`option` roles by the program name, so if you have the following
|
||||
situation ::
|
||||
|
||||
.. program:: rm
|
||||
|
||||
.. cmdoption:: -r
|
||||
|
||||
Work recursively.
|
||||
|
||||
.. program:: svn
|
||||
|
||||
.. cmdoption:: -r revision
|
||||
|
||||
Specify the revision to work upon.
|
||||
|
||||
then ``:option:`rm -r``` would refer to the first option, while
|
||||
``:option:`svn -r``` would refer to the second one.
|
||||
|
||||
The program name may contain spaces (in case you want to document subcommands
|
||||
like ``svn add`` and ``svn commit`` separately).
|
||||
|
||||
.. versionadded:: 0.5
|
||||
|
||||
|
||||
Custom description units
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
There is also a generic version of these directives:
|
||||
|
||||
.. directive:: .. describe:: text
|
||||
|
||||
This directive produces the same formatting as the specific ones explained
|
||||
above but does not create index entries or cross-referencing targets. It is
|
||||
used, for example, to describe the directives in this document. Example::
|
||||
|
||||
.. describe:: opcode
|
||||
|
||||
Describes a Python bytecode instruction.
|
||||
|
||||
Extensions may add more directives like that, using the
|
||||
:func:`~sphinx.application.Sphinx.add_description_unit` method.
|
||||
|
@ -14,10 +14,9 @@ from docutils import nodes
|
||||
from docutils.parsers.rst import directives
|
||||
|
||||
from sphinx import addnodes
|
||||
from sphinx.util import ws_re
|
||||
|
||||
|
||||
ws_re = re.compile(r'\s+')
|
||||
|
||||
# ------ information units ---------------------------------------------------------
|
||||
|
||||
def desc_index_text(desctype, module, name, add_modules):
|
||||
@ -352,17 +351,17 @@ def parse_c_signature(signode, sig, desctype):
|
||||
|
||||
|
||||
option_desc_re = re.compile(
|
||||
r'(/|-|--)([-_a-zA-Z0-9]+)(\s*.*?)(?=,\s+(?:/|-|--)|$)')
|
||||
r'((?:/|-|--)[-_a-zA-Z0-9]+)(\s*.*?)(?=,\s+(?:/|-|--)|$)')
|
||||
|
||||
def parse_option_desc(signode, sig):
|
||||
"""Transform an option description into RST nodes."""
|
||||
count = 0
|
||||
firstname = ''
|
||||
for m in option_desc_re.finditer(sig):
|
||||
prefix, optname, args = m.groups()
|
||||
optname, args = m.groups()
|
||||
if count:
|
||||
signode += addnodes.desc_addname(', ', ', ')
|
||||
signode += addnodes.desc_name(prefix+optname, prefix+optname)
|
||||
signode += addnodes.desc_name(optname, optname)
|
||||
signode += addnodes.desc_addname(args, args)
|
||||
if not count:
|
||||
firstname = optname
|
||||
@ -402,12 +401,17 @@ def desc_directive(desctype, arguments, options, content, lineno,
|
||||
elif desctype == 'cmdoption':
|
||||
optname = parse_option_desc(signode, sig)
|
||||
if not noindex:
|
||||
targetname = 'cmdoption-' + optname
|
||||
targetname = optname.replace('/', '-')
|
||||
if env.currprogram:
|
||||
targetname = '-' + env.currprogram + targetname
|
||||
targetname = 'cmdoption' + targetname
|
||||
signode['ids'].append(targetname)
|
||||
state.document.note_explicit_target(signode)
|
||||
inode['entries'].append(('pair', _('command line option; %s') % sig,
|
||||
targetname, targetname))
|
||||
env.note_reftarget('option', optname, targetname)
|
||||
inode['entries'].append(
|
||||
('pair', _('%scommand line option; %s') %
|
||||
((env.currprogram and env.currprogram + ' ' or ''), sig),
|
||||
targetname, targetname))
|
||||
env.note_progoption(optname, targetname)
|
||||
continue
|
||||
elif desctype == 'describe':
|
||||
signode.clear()
|
||||
|
@ -14,9 +14,8 @@ from docutils import nodes
|
||||
from docutils.parsers.rst import directives
|
||||
|
||||
from sphinx import addnodes
|
||||
from sphinx.util import patfilter
|
||||
from sphinx.roles import caption_ref_re
|
||||
from sphinx.locale import pairindextypes
|
||||
from sphinx.util import patfilter, ws_re, caption_ref_re
|
||||
from sphinx.util.compat import make_admonition
|
||||
|
||||
|
||||
@ -159,6 +158,20 @@ directives.register_directive('sectionauthor', author_directive)
|
||||
directives.register_directive('moduleauthor', author_directive)
|
||||
|
||||
|
||||
def program_directive(name, arguments, options, content, lineno,
|
||||
content_offset, block_text, state, state_machine):
|
||||
env = state.document.settings.env
|
||||
program = ws_re.sub('-', arguments[0].strip())
|
||||
if program == 'None':
|
||||
env.currprogram = None
|
||||
else:
|
||||
env.currprogram = program
|
||||
return []
|
||||
|
||||
program_directive.arguments = (1, 0, 1)
|
||||
directives.register_directive('program', program_directive)
|
||||
|
||||
|
||||
# ------ index markup --------------------------------------------------------------
|
||||
|
||||
indextypes = [
|
||||
|
@ -57,7 +57,7 @@ default_settings = {
|
||||
|
||||
# This is increased every time an environment attribute is added
|
||||
# or changed to properly invalidate pickle files.
|
||||
ENV_VERSION = 25
|
||||
ENV_VERSION = 26
|
||||
|
||||
|
||||
default_substitutions = set([
|
||||
@ -266,8 +266,9 @@ class BuildEnvironment:
|
||||
self.modules = {} # modname -> docname, synopsis, platform, deprecated
|
||||
self.labels = {} # labelname -> docname, labelid, sectionname
|
||||
self.anonlabels = {} # labelname -> docname, labelid
|
||||
self.progoptions = {} # (program, name) -> docname, labelid
|
||||
self.reftargets = {} # (type, name) -> docname, labelid
|
||||
# where type is term, token, option, envvar, citation
|
||||
# where type is term, token, envvar, citation
|
||||
|
||||
# Other inventories
|
||||
self.indexentries = {} # docname -> list of
|
||||
@ -281,6 +282,7 @@ class BuildEnvironment:
|
||||
self.currmodule = None # current module name
|
||||
self.currclass = None # current class name
|
||||
self.currdesc = None # current descref name
|
||||
self.currprogram = None # current program name
|
||||
self.index_num = 0 # autonumber for index targets
|
||||
self.gloss_entries = set() # existing definition labels
|
||||
|
||||
@ -331,6 +333,9 @@ class BuildEnvironment:
|
||||
for key, (fn, _) in self.reftargets.items():
|
||||
if fn == docname:
|
||||
del self.reftargets[key]
|
||||
for key, (fn, _) in self.progoptions.items():
|
||||
if fn == docname:
|
||||
del self.progoptions[key]
|
||||
for version, changes in self.versionchanges.items():
|
||||
new = [change for change in changes if change[1] != docname]
|
||||
changes[:] = new
|
||||
@ -826,6 +831,9 @@ class BuildEnvironment:
|
||||
self.modules[modname] = (self.docname, synopsis, platform, deprecated)
|
||||
self.filemodules.setdefault(self.docname, []).append(modname)
|
||||
|
||||
def note_progoption(self, optname, labelid):
|
||||
self.progoptions[self.currprogram, optname] = (self.docname, labelid)
|
||||
|
||||
def note_reftarget(self, type, name, labelid):
|
||||
self.reftargets[type, name] = (self.docname, labelid)
|
||||
|
||||
@ -968,7 +976,7 @@ class BuildEnvironment:
|
||||
'meth', 'cfunc', 'cmember', 'cdata', 'ctype', 'cmacro'))
|
||||
|
||||
def resolve_references(self, doctree, fromdocname, builder):
|
||||
reftarget_roles = set(('token', 'term', 'option', 'citation'))
|
||||
reftarget_roles = set(('token', 'term', 'citation'))
|
||||
# add all custom xref types too
|
||||
reftarget_roles.update(i[0] for i in additional_xref_types.values())
|
||||
|
||||
@ -1028,6 +1036,19 @@ class BuildEnvironment:
|
||||
newnode['refuri'] = builder.get_relative_uri(
|
||||
fromdocname, docname) + '#' + labelid
|
||||
newnode.append(contnode)
|
||||
elif typ == 'option':
|
||||
progname = node['refprogram']
|
||||
docname, labelid = self.progoptions.get((progname, target), ('', ''))
|
||||
if not docname:
|
||||
newnode = contnode
|
||||
else:
|
||||
newnode = nodes.reference('', '')
|
||||
if docname == fromdocname:
|
||||
newnode['refid'] = labelid
|
||||
else:
|
||||
newnode['refuri'] = builder.get_relative_uri(
|
||||
fromdocname, docname) + '#' + labelid
|
||||
newnode.append(contnode)
|
||||
elif typ in reftarget_roles:
|
||||
docname, labelid = self.reftargets.get((typ, target), ('', ''))
|
||||
if not docname:
|
||||
|
@ -643,6 +643,8 @@ def setup(app):
|
||||
noindex=directives.flag)
|
||||
app.add_directive('autoattribute', auto_directive, 1, (1, 0, 1),
|
||||
noindex=directives.flag)
|
||||
app.add_directive('autoprogram', auto_directive, 1, (1, 0, 1),
|
||||
noindex=directives.flag)
|
||||
# deprecated: remove in some future version.
|
||||
app.add_config_value('automodule_skip_lines', 0, True)
|
||||
app.add_config_value('autoclass_content', 'class', True)
|
||||
|
@ -15,9 +15,8 @@ from docutils import nodes, utils
|
||||
from docutils.parsers.rst import roles
|
||||
|
||||
from sphinx import addnodes
|
||||
from sphinx.util import ws_re, caption_ref_re
|
||||
|
||||
ws_re = re.compile(r'\s+')
|
||||
caption_ref_re = re.compile(r'^([^<]+?)\s*<(.+)>$')
|
||||
|
||||
generic_docroles = {
|
||||
'command' : nodes.strong,
|
||||
@ -143,7 +142,7 @@ def xfileref_role(typ, rawtext, text, lineno, inliner, options={}, content=[]):
|
||||
# fallback: everything after '<' is the target
|
||||
target = text[brace+1:]
|
||||
title = text[:brace]
|
||||
# special target for Python object cross-references
|
||||
# special target for Python object cross-references
|
||||
if typ in ('data', 'exc', 'func', 'class', 'const', 'attr', 'meth', 'mod', 'obj'):
|
||||
# fix-up parentheses in link title
|
||||
if titleistarget:
|
||||
@ -166,9 +165,17 @@ def xfileref_role(typ, rawtext, text, lineno, inliner, options={}, content=[]):
|
||||
target = target[1:]
|
||||
pnode['refspecific'] = True
|
||||
# some other special cases for the target
|
||||
elif typ == 'option' and target[0] in '-/':
|
||||
# strip option marker from target
|
||||
target = target[1:]
|
||||
elif typ == 'option':
|
||||
program = env.currprogram
|
||||
if titleistarget:
|
||||
if ' ' in title and not (title.startswith('/') or title.startswith('-')):
|
||||
program, target = re.split(' (?=-|--|/)', title, 1)
|
||||
program = ws_re.sub('-', program)
|
||||
target = target.strip()
|
||||
elif ' ' in target:
|
||||
program, target = re.split(' (?=-|--|/)', target, 1)
|
||||
program = ws_re.sub('-', program)
|
||||
pnode['refprogram'] = program
|
||||
elif typ == 'term':
|
||||
# normalize whitespace in definition terms (if the term reference is
|
||||
# broken over a line, a newline will be in target)
|
||||
@ -217,21 +224,21 @@ specific_docroles = {
|
||||
'obj': xfileref_role,
|
||||
'cfunc' : xfileref_role,
|
||||
'cmember': xfileref_role,
|
||||
'cdata' : xfileref_role,
|
||||
'ctype' : xfileref_role,
|
||||
'cmacro' : xfileref_role,
|
||||
'cdata': xfileref_role,
|
||||
'ctype': xfileref_role,
|
||||
'cmacro': xfileref_role,
|
||||
|
||||
'mod' : xfileref_role,
|
||||
'mod': xfileref_role,
|
||||
|
||||
'keyword': xfileref_role,
|
||||
'ref': xfileref_role,
|
||||
'token' : xfileref_role,
|
||||
'token': xfileref_role,
|
||||
'term': xfileref_role,
|
||||
'option': xfileref_role,
|
||||
|
||||
'menuselection' : menusel_role,
|
||||
'file' : emph_literal_role,
|
||||
'samp' : emph_literal_role,
|
||||
'menuselection': menusel_role,
|
||||
'file': emph_literal_role,
|
||||
'samp': emph_literal_role,
|
||||
}
|
||||
|
||||
for rolename, func in specific_docroles.iteritems():
|
||||
|
@ -18,6 +18,11 @@ import traceback
|
||||
from os import path
|
||||
|
||||
|
||||
# Generally useful regular expressions.
|
||||
ws_re = re.compile(r'\s+')
|
||||
caption_ref_re = re.compile(r'^([^<]+?)\s*<(.+)>$')
|
||||
|
||||
|
||||
# SEP separates path elements in the canonical file names
|
||||
#
|
||||
# Define SEP as a manifest constant, not so much because we expect it to change
|
||||
|
Loading…
Reference in New Issue
Block a user