mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Convert directives in builtin extensions to class API.
This commit is contained in:
parent
6bfed75113
commit
3724f9020a
@ -23,6 +23,7 @@ from docutils import nodes
|
||||
from docutils.parsers.rst import directives
|
||||
|
||||
from sphinx.builders import Builder
|
||||
from sphinx.util.compat import Directive
|
||||
from sphinx.util.console import bold
|
||||
|
||||
blankline_re = re.compile(r'^\s*<BLANKLINE>', re.MULTILINE)
|
||||
@ -30,13 +31,22 @@ doctestopt_re = re.compile(r'#\s*doctest:.+$', re.MULTILINE)
|
||||
|
||||
# set up the necessary directives
|
||||
|
||||
def test_directive(name, arguments, options, content, lineno,
|
||||
content_offset, block_text, state, state_machine):
|
||||
class TestDirective(Directive):
|
||||
"""
|
||||
Base class for doctest-related directives.
|
||||
"""
|
||||
|
||||
has_content = True
|
||||
required_arguments = 0
|
||||
optional_arguments = 1
|
||||
final_argument_whitespace = True
|
||||
|
||||
def run(self):
|
||||
# use ordinary docutils nodes for test code: they get special attributes
|
||||
# so that our builder recognizes them, and the other builders are happy.
|
||||
code = '\n'.join(content)
|
||||
code = '\n'.join(self.content)
|
||||
test = None
|
||||
if name == 'doctest':
|
||||
if self.name == 'doctest':
|
||||
if '<BLANKLINE>' in code:
|
||||
# convert <BLANKLINE>s to ordinary blank lines for presentation
|
||||
test = code
|
||||
@ -46,24 +56,24 @@ def test_directive(name, arguments, options, content, lineno,
|
||||
test = code
|
||||
code = doctestopt_re.sub('', code)
|
||||
nodetype = nodes.literal_block
|
||||
if name == 'testsetup' or 'hide' in options:
|
||||
if self.name == 'testsetup' or 'hide' in self.options:
|
||||
nodetype = nodes.comment
|
||||
if arguments:
|
||||
groups = [x.strip() for x in arguments[0].split(',')]
|
||||
if self.arguments:
|
||||
groups = [x.strip() for x in self.arguments[0].split(',')]
|
||||
else:
|
||||
groups = ['default']
|
||||
node = nodetype(code, code, testnodetype=name, groups=groups)
|
||||
node.line = lineno
|
||||
node = nodetype(code, code, testnodetype=self.name, groups=groups)
|
||||
node.line = self.lineno
|
||||
if test is not None:
|
||||
# only save if it differs from code
|
||||
node['test'] = test
|
||||
if name == 'testoutput':
|
||||
if self.name == 'testoutput':
|
||||
# don't try to highlight output
|
||||
node['language'] = 'none'
|
||||
node['options'] = {}
|
||||
if name in ('doctest', 'testoutput') and 'options' in options:
|
||||
if self.name in ('doctest', 'testoutput') and 'options' in self.options:
|
||||
# parse doctest-like output comparison flags
|
||||
option_strings = options['options'].replace(',', ' ').split()
|
||||
option_strings = self.options['options'].replace(',', ' ').split()
|
||||
for option in option_strings:
|
||||
if (option[0] not in '+-' or option[1:] not in
|
||||
doctest.OPTIONFLAGS_BY_NAME):
|
||||
@ -73,20 +83,25 @@ def test_directive(name, arguments, options, content, lineno,
|
||||
node['options'][flag] = (option[0] == '+')
|
||||
return [node]
|
||||
|
||||
# need to have individual functions for each directive due to different
|
||||
# options they accept
|
||||
class TestsetupDirective(TestDirective):
|
||||
option_spec = {}
|
||||
|
||||
def testsetup_directive(*args):
|
||||
return test_directive(*args)
|
||||
class DoctestDirective(TestDirective):
|
||||
option_spec = {
|
||||
'hide': directives.flag,
|
||||
'options': directives.unchanged,
|
||||
}
|
||||
|
||||
def doctest_directive(*args):
|
||||
return test_directive(*args)
|
||||
class TestcodeDirective(TestDirective):
|
||||
option_spec = {
|
||||
'hide': directives.flag,
|
||||
}
|
||||
|
||||
def testcode_directive(*args):
|
||||
return test_directive(*args)
|
||||
|
||||
def testoutput_directive(*args):
|
||||
return test_directive(*args)
|
||||
class TestoutputDirective(TestDirective):
|
||||
option_spec = {
|
||||
'hide': directives.flag,
|
||||
'options': directives.unchanged,
|
||||
}
|
||||
|
||||
|
||||
parser = doctest.DocTestParser()
|
||||
@ -334,13 +349,10 @@ Doctest summary
|
||||
|
||||
|
||||
def setup(app):
|
||||
app.add_directive('testsetup', testsetup_directive, 1, (0, 1, 1))
|
||||
app.add_directive('doctest', doctest_directive, 1, (0, 1, 1),
|
||||
hide=directives.flag, options=directives.unchanged)
|
||||
app.add_directive('testcode', testcode_directive, 1, (0, 1, 1),
|
||||
hide=directives.flag)
|
||||
app.add_directive('testoutput', testoutput_directive, 1, (0, 1, 1),
|
||||
hide=directives.flag, options=directives.unchanged)
|
||||
app.add_directive('testsetup', TestsetupDirective)
|
||||
app.add_directive('doctest', DoctestDirective)
|
||||
app.add_directive('testcode', TestcodeDirective)
|
||||
app.add_directive('testoutput', TestoutputDirective)
|
||||
app.add_builder(DocTestBuilder)
|
||||
# this config value adds to sys.path
|
||||
app.add_config_value('doctest_path', [], False)
|
||||
|
@ -22,16 +22,26 @@
|
||||
|
||||
from docutils import nodes
|
||||
|
||||
from sphinx.util.compat import Directive
|
||||
|
||||
|
||||
class ifconfig(nodes.Element): pass
|
||||
|
||||
|
||||
def ifconfig_directive(name, arguments, options, content, lineno,
|
||||
content_offset, block_text, state, state_machine):
|
||||
class IfConfig(Directive):
|
||||
|
||||
has_content = True
|
||||
required_arguments = 1
|
||||
optional_arguments = 0
|
||||
final_argument_whitespace = True
|
||||
option_spec = {}
|
||||
|
||||
def run(self):
|
||||
node = ifconfig()
|
||||
node.line = lineno
|
||||
node['expr'] = arguments[0]
|
||||
state.nested_parse(content, content_offset, node)
|
||||
node.document = self.state.document
|
||||
node.line = self.lineno
|
||||
node['expr'] = self.arguments[0]
|
||||
self.state.nested_parse(self.content, self.content_offset, node)
|
||||
return [node]
|
||||
|
||||
|
||||
@ -58,5 +68,5 @@ def process_ifconfig_nodes(app, doctree, docname):
|
||||
|
||||
def setup(app):
|
||||
app.add_node(ifconfig)
|
||||
app.add_directive('ifconfig', ifconfig_directive, 1, (1, 0, 1))
|
||||
app.add_directive('ifconfig', IfConfig)
|
||||
app.connect('doctree-resolved', process_ifconfig_nodes)
|
||||
|
@ -12,6 +12,8 @@
|
||||
from docutils import nodes, utils
|
||||
from docutils.parsers.rst import directives
|
||||
|
||||
from sphinx.util.compat import Directive
|
||||
|
||||
|
||||
class math(nodes.Inline, nodes.TextElement):
|
||||
pass
|
||||
@ -45,20 +47,31 @@ def eq_role(role, rawtext, text, lineno, inliner, options={}, content=[]):
|
||||
node['docname'] = inliner.document.settings.env.docname
|
||||
return [node], []
|
||||
|
||||
def math_directive(name, arguments, options, content, lineno,
|
||||
content_offset, block_text, state, state_machine):
|
||||
latex = '\n'.join(content)
|
||||
if arguments and arguments[0]:
|
||||
latex = arguments[0] + '\n\n' + latex
|
||||
|
||||
class MathDirective(Directive):
|
||||
|
||||
has_content = True
|
||||
required_arguments = 0
|
||||
optional_arguments = 1
|
||||
final_argument_whitespace = True
|
||||
option_spec = {
|
||||
'label': directives.unchanged,
|
||||
'nowrap': directives.flag,
|
||||
}
|
||||
|
||||
def run(self):
|
||||
latex = '\n'.join(self.content)
|
||||
if self.arguments and self.arguments[0]:
|
||||
latex = self.arguments[0] + '\n\n' + latex
|
||||
node = displaymath()
|
||||
node['latex'] = latex
|
||||
node['label'] = options.get('label', None)
|
||||
node['nowrap'] = 'nowrap' in options
|
||||
node['docname'] = state.document.settings.env.docname
|
||||
node['label'] = self.options.get('label', None)
|
||||
node['nowrap'] = 'nowrap' in self.options
|
||||
node['docname'] = self.state.document.settings.env.docname
|
||||
ret = [node]
|
||||
if node['label']:
|
||||
tnode = nodes.target('', '', ids=['equation-' + node['label']])
|
||||
state.document.note_explicit_target(tnode)
|
||||
self.state.document.note_explicit_target(tnode)
|
||||
ret.insert(0, tnode)
|
||||
return ret
|
||||
|
||||
@ -134,6 +147,5 @@ def setup(app, htmlinlinevisitors, htmldisplayvisitors):
|
||||
html=(html_visit_eqref, html_depart_eqref))
|
||||
app.add_role('math', math_role)
|
||||
app.add_role('eq', eq_role)
|
||||
app.add_directive('math', math_directive, 1, (0, 1, 1),
|
||||
label=directives.unchanged, nowrap=directives.flag)
|
||||
app.add_directive('math', MathDirective)
|
||||
app.connect('doctree-resolved', number_equations)
|
||||
|
@ -14,22 +14,33 @@
|
||||
|
||||
from docutils import nodes
|
||||
|
||||
from sphinx.util.compat import make_admonition
|
||||
from sphinx.util.compat import Directive, make_admonition
|
||||
|
||||
class todo_node(nodes.Admonition, nodes.Element): pass
|
||||
class todolist(nodes.General, nodes.Element): pass
|
||||
|
||||
|
||||
def todo_directive(name, arguments, options, content, lineno,
|
||||
content_offset, block_text, state, state_machine):
|
||||
env = state.document.settings.env
|
||||
class Todo(Directive):
|
||||
"""
|
||||
A todo entry, displayed (if configured) in the form of an admonition.
|
||||
"""
|
||||
|
||||
has_content = True
|
||||
required_arguments = 0
|
||||
optional_arguments = 0
|
||||
final_argument_whitespace = False
|
||||
option_spec = {}
|
||||
|
||||
def run(self):
|
||||
env = self.state.document.settings.env
|
||||
|
||||
targetid = "todo-%s" % env.index_num
|
||||
env.index_num += 1
|
||||
targetnode = nodes.target('', '', ids=[targetid])
|
||||
|
||||
ad = make_admonition(todo_node, name, [_('Todo')], options, content, lineno,
|
||||
content_offset, block_text, state, state_machine)
|
||||
ad = make_admonition(todo_node, self.name, [_('Todo')], self.options,
|
||||
self.content, self.lineno, self.content_offset,
|
||||
self.block_text, self.state, self.state_machine)
|
||||
|
||||
# Attach a list of all todos to the environment,
|
||||
# the todolist works with the collected todo nodes
|
||||
@ -37,7 +48,7 @@ def todo_directive(name, arguments, options, content, lineno,
|
||||
env.todo_all_todos = []
|
||||
env.todo_all_todos.append({
|
||||
'docname': env.docname,
|
||||
'lineno': lineno,
|
||||
'lineno': self.lineno,
|
||||
'todo': ad[0].deepcopy(),
|
||||
'target': targetnode,
|
||||
})
|
||||
@ -45,8 +56,18 @@ def todo_directive(name, arguments, options, content, lineno,
|
||||
return [targetnode] + ad
|
||||
|
||||
|
||||
def todolist_directive(name, arguments, options, content, lineno,
|
||||
content_offset, block_text, state, state_machine):
|
||||
class TodoList(Directive):
|
||||
"""
|
||||
A list of all todo entries.
|
||||
"""
|
||||
|
||||
has_content = False
|
||||
required_arguments = 0
|
||||
optional_arguments = 0
|
||||
final_argument_whitespace = False
|
||||
option_spec = {}
|
||||
|
||||
def run(self):
|
||||
# Simply insert an empty todolist node which will be replaced later
|
||||
# when process_todo_nodes is called
|
||||
return [todolist('')]
|
||||
@ -119,8 +140,8 @@ def setup(app):
|
||||
latex=(visit_todo_node, depart_todo_node),
|
||||
text=(visit_todo_node, depart_todo_node))
|
||||
|
||||
app.add_directive('todo', todo_directive, 1, (0, 0, 1))
|
||||
app.add_directive('todolist', todolist_directive, 0, (0, 0, 0))
|
||||
app.add_directive('todo', Todo)
|
||||
app.add_directive('todolist', TodoList)
|
||||
app.connect('doctree-resolved', process_todo_nodes)
|
||||
app.connect('env-purge-doc', purge_todos)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user