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