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.parsers.rst import Directive, directives
|
||||
from docutils.statemachine import ViewList
|
||||
|
||||
from six import string_types
|
||||
|
||||
@ -61,6 +62,17 @@ def dedent_lines(lines, dedent):
|
||||
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):
|
||||
"""
|
||||
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['language'] = self.arguments[0]
|
||||
caption = self.options.get('caption')
|
||||
if caption:
|
||||
literal['caption'] = caption
|
||||
literal['linenos'] = 'linenos' in self.options or \
|
||||
'lineno-start' in self.options
|
||||
extra_args = literal['highlight_args'] = {}
|
||||
@ -111,6 +120,11 @@ class CodeBlock(Directive):
|
||||
if 'lineno-start' in self.options:
|
||||
extra_args['linenostart'] = self.options['lineno-start']
|
||||
set_source_info(self, literal)
|
||||
|
||||
caption = self.options.get('caption')
|
||||
if caption:
|
||||
literal = container_wrapper(self, literal, caption)
|
||||
|
||||
return [literal]
|
||||
|
||||
|
||||
@ -268,17 +282,20 @@ class LiteralInclude(Directive):
|
||||
retnode['language'] = self.options['language']
|
||||
retnode['linenos'] = 'linenos' in self.options or \
|
||||
'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'] = {}
|
||||
if hl_lines is not None:
|
||||
extra_args['hl_lines'] = hl_lines
|
||||
if 'lineno-start' in self.options:
|
||||
extra_args['linenostart'] = self.options['lineno-start']
|
||||
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]
|
||||
|
||||
|
||||
|
@ -562,9 +562,11 @@ class StandardDomain(Domain):
|
||||
break
|
||||
else:
|
||||
continue
|
||||
elif node.tagname == 'literal_block':
|
||||
if 'caption' in node:
|
||||
sectname = node['caption']
|
||||
elif node.tagname == 'container' and node.get('literal_block'):
|
||||
for n in node:
|
||||
if n.tagname == 'caption':
|
||||
sectname = clean_astext(n)
|
||||
break
|
||||
else:
|
||||
continue
|
||||
else:
|
||||
|
@ -484,8 +484,7 @@ div.code-block-filename code {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
div.code-block-caption + pre,
|
||||
div.code-block-caption + div.highlight > pre {
|
||||
div.code-block-caption + div > div.highlight > pre {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
|
@ -283,12 +283,21 @@ class HTMLTranslator(BaseTranslator):
|
||||
**highlight_args)
|
||||
starttag = self.starttag(node, 'div', suffix='',
|
||||
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')
|
||||
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):
|
||||
self.visit_literal_block(node)
|
||||
|
||||
|
@ -266,6 +266,7 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
||||
self.next_section_ids = set()
|
||||
self.next_figure_ids = set()
|
||||
self.next_table_ids = set()
|
||||
self.next_literal_ids = set()
|
||||
# flags
|
||||
self.in_title = 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.update(node['ids'])
|
||||
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:
|
||||
pass
|
||||
if 'refuri' in node:
|
||||
@ -1345,10 +1352,6 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
||||
highlight_args['force'] = True
|
||||
if 'linenos' in node:
|
||||
linenos = node['linenos']
|
||||
caption = node.get('caption')
|
||||
if caption:
|
||||
self.body.append('\n\\begin{literal-block}\caption{%s}\n' %
|
||||
(caption,))
|
||||
def warner(msg):
|
||||
self.builder.warn(msg, (self.curfilestack[-1], node.line))
|
||||
hlcode = self.highlighter.highlight_block(code, lang, warn=warner,
|
||||
@ -1366,8 +1369,6 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
||||
hlcode = hlcode.rstrip() + '\n'
|
||||
self.body.append('\n' + hlcode + '\\end{%sVerbatim}\n' %
|
||||
(self.table and 'Original' or ''))
|
||||
if caption:
|
||||
self.body.append('\n\\end{literal-block}\n')
|
||||
raise nodes.SkipNode
|
||||
def depart_literal_block(self, node):
|
||||
self.body.append('\n\\end{alltt}\n')
|
||||
@ -1495,9 +1496,16 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
||||
pass
|
||||
|
||||
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):
|
||||
pass
|
||||
if node.get('literal_block'):
|
||||
self.body.append('\\end{literal-block}\n')
|
||||
|
||||
def visit_decoration(self, node):
|
||||
pass
|
||||
|
@ -1054,9 +1054,11 @@ class TexinfoTranslator(nodes.NodeVisitor):
|
||||
raise nodes.SkipNode
|
||||
|
||||
def visit_container(self, node):
|
||||
pass
|
||||
if node.get('literal_block'):
|
||||
self.body.append('\n\n@float LiteralBlock\n')
|
||||
def depart_container(self, node):
|
||||
pass
|
||||
if node.get('literal_block'):
|
||||
self.body.append('\n@end float\n\n')
|
||||
|
||||
def visit_decoration(self, node):
|
||||
pass
|
||||
@ -1095,13 +1097,15 @@ class TexinfoTranslator(nodes.NodeVisitor):
|
||||
self.body.append('\n@end float\n\n')
|
||||
|
||||
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.curfilestack[-1], node.line))
|
||||
return
|
||||
self.body.append('\n@caption{')
|
||||
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')
|
||||
|
||||
def visit_image(self, node):
|
||||
|
@ -5,7 +5,7 @@ Code blocks
|
||||
-----------
|
||||
|
||||
.. code-block:: ruby
|
||||
:caption: caption-test.rb
|
||||
:caption: caption *test* rb
|
||||
|
||||
def ruby?
|
||||
false
|
||||
@ -17,5 +17,5 @@ Literal Include
|
||||
|
||||
.. literalinclude:: literal.inc
|
||||
:language: python
|
||||
:caption: caption-test.py
|
||||
:caption: caption **test** py
|
||||
:lines: 10-11
|
||||
|
@ -53,7 +53,7 @@ def test_code_block_dedent(app, status, warning):
|
||||
def test_code_block_caption_html(app, status, warning):
|
||||
app.builder.build(['caption'])
|
||||
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
|
||||
|
||||
|
||||
@ -61,7 +61,7 @@ def test_code_block_caption_html(app, status, warning):
|
||||
def test_code_block_caption_latex(app, status, warning):
|
||||
app.builder.build_all()
|
||||
latex = (app.outdir / 'Python.tex').text()
|
||||
caption = '\\caption{caption-test.rb}'
|
||||
caption = '\\caption{\ncaption \\emph{test} rb\n}'
|
||||
assert caption in latex
|
||||
|
||||
|
||||
@ -99,7 +99,7 @@ def test_literal_include_dedent(app, status, warning):
|
||||
def test_literalinclude_caption_html(app, status, warning):
|
||||
app.builder.build('index')
|
||||
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
|
||||
|
||||
|
||||
@ -107,5 +107,5 @@ def test_literalinclude_caption_html(app, status, warning):
|
||||
def test_literalinclude_caption_latex(app, status, warning):
|
||||
app.builder.build('index')
|
||||
latex = (app.outdir / 'Python.tex').text()
|
||||
caption = '\\caption{caption-test.py}'
|
||||
caption = '\\caption{\ncaption \\textbf{test} py\n}'
|
||||
assert caption in latex
|
||||
|
Loading…
Reference in New Issue
Block a user