mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Merged in tk0miya/sphinx (pull request #292)
do nested_parse() :caption: of code-block directive
This commit is contained in:
commit
7984f81a5e
@ -13,6 +13,7 @@ from difflib import unified_diff
|
|||||||
|
|
||||||
from docutils import nodes
|
from docutils import nodes
|
||||||
from docutils.parsers.rst import Directive, directives
|
from docutils.parsers.rst import Directive, directives
|
||||||
|
from docutils.statemachine import ViewList
|
||||||
|
|
||||||
from six import string_types
|
from six import string_types
|
||||||
|
|
||||||
@ -61,6 +62,17 @@ def dedent_lines(lines, dedent):
|
|||||||
return new_lines
|
return new_lines
|
||||||
|
|
||||||
|
|
||||||
|
def container_wrapper(directive, literal_node, caption):
|
||||||
|
caption_node = nodes.caption()
|
||||||
|
directive.state.nested_parse(ViewList([caption], source=''),
|
||||||
|
directive.content_offset, caption_node)
|
||||||
|
|
||||||
|
container_node = nodes.container('', literal_block=True)
|
||||||
|
container_node += caption_node
|
||||||
|
container_node += literal_node
|
||||||
|
return container_node
|
||||||
|
|
||||||
|
|
||||||
class CodeBlock(Directive):
|
class CodeBlock(Directive):
|
||||||
"""
|
"""
|
||||||
Directive for a code block with special highlighting or line numbering
|
Directive for a code block with special highlighting or line numbering
|
||||||
@ -100,9 +112,6 @@ class CodeBlock(Directive):
|
|||||||
|
|
||||||
literal = nodes.literal_block(code, code)
|
literal = nodes.literal_block(code, code)
|
||||||
literal['language'] = self.arguments[0]
|
literal['language'] = self.arguments[0]
|
||||||
caption = self.options.get('caption')
|
|
||||||
if caption:
|
|
||||||
literal['caption'] = caption
|
|
||||||
literal['linenos'] = 'linenos' in self.options or \
|
literal['linenos'] = 'linenos' in self.options or \
|
||||||
'lineno-start' in self.options
|
'lineno-start' in self.options
|
||||||
extra_args = literal['highlight_args'] = {}
|
extra_args = literal['highlight_args'] = {}
|
||||||
@ -111,6 +120,11 @@ class CodeBlock(Directive):
|
|||||||
if 'lineno-start' in self.options:
|
if 'lineno-start' in self.options:
|
||||||
extra_args['linenostart'] = self.options['lineno-start']
|
extra_args['linenostart'] = self.options['lineno-start']
|
||||||
set_source_info(self, literal)
|
set_source_info(self, literal)
|
||||||
|
|
||||||
|
caption = self.options.get('caption')
|
||||||
|
if caption:
|
||||||
|
literal = container_wrapper(self, literal, caption)
|
||||||
|
|
||||||
return [literal]
|
return [literal]
|
||||||
|
|
||||||
|
|
||||||
@ -268,17 +282,20 @@ class LiteralInclude(Directive):
|
|||||||
retnode['language'] = self.options['language']
|
retnode['language'] = self.options['language']
|
||||||
retnode['linenos'] = 'linenos' in self.options or \
|
retnode['linenos'] = 'linenos' in self.options or \
|
||||||
'lineno-start' in self.options
|
'lineno-start' in self.options
|
||||||
caption = self.options.get('caption')
|
|
||||||
if caption is not None:
|
|
||||||
if not caption:
|
|
||||||
caption = self.arguments[0]
|
|
||||||
retnode['caption'] = caption
|
|
||||||
extra_args = retnode['highlight_args'] = {}
|
extra_args = retnode['highlight_args'] = {}
|
||||||
if hl_lines is not None:
|
if hl_lines is not None:
|
||||||
extra_args['hl_lines'] = hl_lines
|
extra_args['hl_lines'] = hl_lines
|
||||||
if 'lineno-start' in self.options:
|
if 'lineno-start' in self.options:
|
||||||
extra_args['linenostart'] = self.options['lineno-start']
|
extra_args['linenostart'] = self.options['lineno-start']
|
||||||
env.note_dependency(rel_filename)
|
env.note_dependency(rel_filename)
|
||||||
|
|
||||||
|
caption = self.options.get('caption')
|
||||||
|
if caption is not None:
|
||||||
|
if caption:
|
||||||
|
retnode = container_wrapper(self, retnode, caption)
|
||||||
|
else:
|
||||||
|
retnode = container_wrapper(self, retnode, self.arguments[0])
|
||||||
|
|
||||||
return [retnode]
|
return [retnode]
|
||||||
|
|
||||||
|
|
||||||
|
@ -562,9 +562,11 @@ class StandardDomain(Domain):
|
|||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
continue
|
continue
|
||||||
elif node.tagname == 'literal_block':
|
elif node.tagname == 'container' and node.get('literal_block'):
|
||||||
if 'caption' in node:
|
for n in node:
|
||||||
sectname = node['caption']
|
if n.tagname == 'caption':
|
||||||
|
sectname = clean_astext(n)
|
||||||
|
break
|
||||||
else:
|
else:
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
|
@ -484,8 +484,7 @@ div.code-block-filename code {
|
|||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
div.code-block-caption + pre,
|
div.code-block-caption + div > div.highlight > pre {
|
||||||
div.code-block-caption + div.highlight > pre {
|
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -283,12 +283,21 @@ class HTMLTranslator(BaseTranslator):
|
|||||||
**highlight_args)
|
**highlight_args)
|
||||||
starttag = self.starttag(node, 'div', suffix='',
|
starttag = self.starttag(node, 'div', suffix='',
|
||||||
CLASS='highlight-%s' % lang)
|
CLASS='highlight-%s' % lang)
|
||||||
if 'caption' in node:
|
|
||||||
starttag += '<div class="code-block-caption"><code>%s</code></div>' % (
|
|
||||||
node['caption'],)
|
|
||||||
self.body.append(starttag + highlighted + '</div>\n')
|
self.body.append(starttag + highlighted + '</div>\n')
|
||||||
raise nodes.SkipNode
|
raise nodes.SkipNode
|
||||||
|
|
||||||
|
def visit_caption(self, node):
|
||||||
|
if isinstance(node.parent, nodes.container) and node.parent.get('literal_block'):
|
||||||
|
self.body.append(self.starttag(node, 'div', '', CLASS='code-block-caption'))
|
||||||
|
else:
|
||||||
|
BaseTranslator.visit_caption(self, node)
|
||||||
|
|
||||||
|
def depart_caption(self, node):
|
||||||
|
if isinstance(node.parent, nodes.container) and node.parent.get('literal_block'):
|
||||||
|
self.body.append('</div>\n')
|
||||||
|
else:
|
||||||
|
BaseTranslator.depart_caption(self, node)
|
||||||
|
|
||||||
def visit_doctest_block(self, node):
|
def visit_doctest_block(self, node):
|
||||||
self.visit_literal_block(node)
|
self.visit_literal_block(node)
|
||||||
|
|
||||||
|
@ -266,6 +266,7 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
|||||||
self.next_section_ids = set()
|
self.next_section_ids = set()
|
||||||
self.next_figure_ids = set()
|
self.next_figure_ids = set()
|
||||||
self.next_table_ids = set()
|
self.next_table_ids = set()
|
||||||
|
self.next_literal_ids = set()
|
||||||
# flags
|
# flags
|
||||||
self.in_title = 0
|
self.in_title = 0
|
||||||
self.in_production_list = 0
|
self.in_production_list = 0
|
||||||
@ -1109,6 +1110,12 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
|||||||
self.next_table_ids.add(node['refid'])
|
self.next_table_ids.add(node['refid'])
|
||||||
self.next_table_ids.update(node['ids'])
|
self.next_table_ids.update(node['ids'])
|
||||||
return
|
return
|
||||||
|
elif isinstance(next, nodes.container) and next.get('literal_block'):
|
||||||
|
# same for literal_block, but only if they have a caption
|
||||||
|
if node.get('refid'):
|
||||||
|
self.next_literal_ids.add(node['refid'])
|
||||||
|
self.next_literal_ids.update(node['ids'])
|
||||||
|
return
|
||||||
except IndexError:
|
except IndexError:
|
||||||
pass
|
pass
|
||||||
if 'refuri' in node:
|
if 'refuri' in node:
|
||||||
@ -1345,10 +1352,6 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
|||||||
highlight_args['force'] = True
|
highlight_args['force'] = True
|
||||||
if 'linenos' in node:
|
if 'linenos' in node:
|
||||||
linenos = node['linenos']
|
linenos = node['linenos']
|
||||||
caption = node.get('caption')
|
|
||||||
if caption:
|
|
||||||
self.body.append('\n\\begin{literal-block}\caption{%s}\n' %
|
|
||||||
(caption,))
|
|
||||||
def warner(msg):
|
def warner(msg):
|
||||||
self.builder.warn(msg, (self.curfilestack[-1], node.line))
|
self.builder.warn(msg, (self.curfilestack[-1], node.line))
|
||||||
hlcode = self.highlighter.highlight_block(code, lang, warn=warner,
|
hlcode = self.highlighter.highlight_block(code, lang, warn=warner,
|
||||||
@ -1366,8 +1369,6 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
|||||||
hlcode = hlcode.rstrip() + '\n'
|
hlcode = hlcode.rstrip() + '\n'
|
||||||
self.body.append('\n' + hlcode + '\\end{%sVerbatim}\n' %
|
self.body.append('\n' + hlcode + '\\end{%sVerbatim}\n' %
|
||||||
(self.table and 'Original' or ''))
|
(self.table and 'Original' or ''))
|
||||||
if caption:
|
|
||||||
self.body.append('\n\\end{literal-block}\n')
|
|
||||||
raise nodes.SkipNode
|
raise nodes.SkipNode
|
||||||
def depart_literal_block(self, node):
|
def depart_literal_block(self, node):
|
||||||
self.body.append('\n\\end{alltt}\n')
|
self.body.append('\n\\end{alltt}\n')
|
||||||
@ -1495,9 +1496,16 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
def visit_container(self, node):
|
def visit_container(self, node):
|
||||||
pass
|
if node.get('literal_block'):
|
||||||
|
ids = ''
|
||||||
|
for id in self.next_literal_ids:
|
||||||
|
ids += self.hypertarget(id, anchor=False)
|
||||||
|
self.next_literal_ids.clear()
|
||||||
|
self.body.append('\n\\begin{literal-block}' + ids)
|
||||||
|
|
||||||
def depart_container(self, node):
|
def depart_container(self, node):
|
||||||
pass
|
if node.get('literal_block'):
|
||||||
|
self.body.append('\\end{literal-block}\n')
|
||||||
|
|
||||||
def visit_decoration(self, node):
|
def visit_decoration(self, node):
|
||||||
pass
|
pass
|
||||||
|
@ -1054,9 +1054,11 @@ class TexinfoTranslator(nodes.NodeVisitor):
|
|||||||
raise nodes.SkipNode
|
raise nodes.SkipNode
|
||||||
|
|
||||||
def visit_container(self, node):
|
def visit_container(self, node):
|
||||||
pass
|
if node.get('literal_block'):
|
||||||
|
self.body.append('\n\n@float LiteralBlock\n')
|
||||||
def depart_container(self, node):
|
def depart_container(self, node):
|
||||||
pass
|
if node.get('literal_block'):
|
||||||
|
self.body.append('\n@end float\n\n')
|
||||||
|
|
||||||
def visit_decoration(self, node):
|
def visit_decoration(self, node):
|
||||||
pass
|
pass
|
||||||
@ -1095,13 +1097,15 @@ class TexinfoTranslator(nodes.NodeVisitor):
|
|||||||
self.body.append('\n@end float\n\n')
|
self.body.append('\n@end float\n\n')
|
||||||
|
|
||||||
def visit_caption(self, node):
|
def visit_caption(self, node):
|
||||||
if not isinstance(node.parent, nodes.figure):
|
if (isinstance(node.parent, nodes.figure) or
|
||||||
|
(isinstance(node.parent, nodes.container) and node.parent.get('literal_block'))):
|
||||||
|
self.body.append('\n@caption{')
|
||||||
|
else:
|
||||||
self.builder.warn('caption not inside a figure.',
|
self.builder.warn('caption not inside a figure.',
|
||||||
(self.curfilestack[-1], node.line))
|
(self.curfilestack[-1], node.line))
|
||||||
return
|
|
||||||
self.body.append('\n@caption{')
|
|
||||||
def depart_caption(self, node):
|
def depart_caption(self, node):
|
||||||
if isinstance(node.parent, nodes.figure):
|
if (isinstance(node.parent, nodes.figure) or
|
||||||
|
(isinstance(node.parent, nodes.container) and node.parent.get('literal_block'))):
|
||||||
self.body.append('}\n')
|
self.body.append('}\n')
|
||||||
|
|
||||||
def visit_image(self, node):
|
def visit_image(self, node):
|
||||||
|
@ -5,7 +5,7 @@ Code blocks
|
|||||||
-----------
|
-----------
|
||||||
|
|
||||||
.. code-block:: ruby
|
.. code-block:: ruby
|
||||||
:caption: caption-test.rb
|
:caption: caption *test* rb
|
||||||
|
|
||||||
def ruby?
|
def ruby?
|
||||||
false
|
false
|
||||||
@ -17,5 +17,5 @@ Literal Include
|
|||||||
|
|
||||||
.. literalinclude:: literal.inc
|
.. literalinclude:: literal.inc
|
||||||
:language: python
|
:language: python
|
||||||
:caption: caption-test.py
|
:caption: caption **test** py
|
||||||
:lines: 10-11
|
:lines: 10-11
|
||||||
|
@ -53,7 +53,7 @@ def test_code_block_dedent(app, status, warning):
|
|||||||
def test_code_block_caption_html(app, status, warning):
|
def test_code_block_caption_html(app, status, warning):
|
||||||
app.builder.build(['caption'])
|
app.builder.build(['caption'])
|
||||||
html = (app.outdir / 'caption.html').text()
|
html = (app.outdir / 'caption.html').text()
|
||||||
caption = '<div class="code-block-caption"><code>caption-test.rb</code></div>'
|
caption = '<div class="code-block-caption">caption <em>test</em> rb</div>'
|
||||||
assert caption in html
|
assert caption in html
|
||||||
|
|
||||||
|
|
||||||
@ -61,7 +61,7 @@ def test_code_block_caption_html(app, status, warning):
|
|||||||
def test_code_block_caption_latex(app, status, warning):
|
def test_code_block_caption_latex(app, status, warning):
|
||||||
app.builder.build_all()
|
app.builder.build_all()
|
||||||
latex = (app.outdir / 'Python.tex').text()
|
latex = (app.outdir / 'Python.tex').text()
|
||||||
caption = '\\caption{caption-test.rb}'
|
caption = '\\caption{\ncaption \\emph{test} rb\n}'
|
||||||
assert caption in latex
|
assert caption in latex
|
||||||
|
|
||||||
|
|
||||||
@ -99,7 +99,7 @@ def test_literal_include_dedent(app, status, warning):
|
|||||||
def test_literalinclude_caption_html(app, status, warning):
|
def test_literalinclude_caption_html(app, status, warning):
|
||||||
app.builder.build('index')
|
app.builder.build('index')
|
||||||
html = (app.outdir / 'caption.html').text()
|
html = (app.outdir / 'caption.html').text()
|
||||||
caption = '<div class="code-block-caption"><code>caption-test.py</code></div>'
|
caption = '<div class="code-block-caption">caption <strong>test</strong> py</div>'
|
||||||
assert caption in html
|
assert caption in html
|
||||||
|
|
||||||
|
|
||||||
@ -107,5 +107,5 @@ def test_literalinclude_caption_html(app, status, warning):
|
|||||||
def test_literalinclude_caption_latex(app, status, warning):
|
def test_literalinclude_caption_latex(app, status, warning):
|
||||||
app.builder.build('index')
|
app.builder.build('index')
|
||||||
latex = (app.outdir / 'Python.tex').text()
|
latex = (app.outdir / 'Python.tex').text()
|
||||||
caption = '\\caption{caption-test.py}'
|
caption = '\\caption{\ncaption \\textbf{test} py\n}'
|
||||||
assert caption in latex
|
assert caption in latex
|
||||||
|
Loading…
Reference in New Issue
Block a user