def apply(self):
def has_child(node, cls):
return any(isinstance(child, cls) for child in node)
for node in self.document.traverse(nodes.Element):
if isinstance(node, nodes.figure):
if has_child(node, nodes.caption):
self.document.note_implicit_target(node)
elif isinstance(node, nodes.image):
if node.parent and has_child(node.parent, nodes.caption):
self.document.note_implicit_target(node.parent)
elif isinstance(node, nodes.table):
if has_child(node, nodes.title):
self.document.note_implicit_target(node)
elif isinstance(node, nodes.literal_block):
if node.parent and has_child(node.parent, nodes.caption):
self.document.note_implicit_target(node.parent)
python类caption()的实例源码
def __init__(self):
self.col = 0
self.colcount = 0
self.colspec = None
self.rowcount = 0
self.had_head = False
self.has_problematic = False
self.has_verbatim = False
self.caption = None
self.longtable = False
def depart_title(self, node):
self.in_title = 0
if isinstance(node.parent, nodes.table):
self.table.caption = self.popbody()
else:
self.body.append(self.context.pop())
self.unrestrict_footnote(node)
def visit_figure(self, node):
ids = ''
if node.get('refuri'):
ids += self.hypertarget(node['refuri'], withdoc=False, anchor=False)
for id in sorted(self.pop_hyperlink_ids('figure')):
ids += self.hypertarget(id, anchor=False)
if node['ids']:
ids += self.hypertarget(node['ids'][0], anchor=False)
if (len(node.children) and
isinstance(node.children[0], nodes.image) and
node.children[0]['ids']):
ids += self.hypertarget(node.children[0]['ids'][0], anchor=False)
for c in node.children:
if isinstance(c, nodes.caption):
caption = c.astext()
node.caption = caption
ids += self.hypertarget('figure:%s' % caption,
withdoc=False,
anchor=False)
break
self.restrict_footnote(node)
self.body.append('\\begin{figure}[tb]\\begin{center}')
# The context is added to the body in depart_figure()
if ids:
self.context.append(ids)
self.context.append('\\end{center}\\end{figure}\n')
def visit_caption(self, node):
self.in_caption += 1
if self.in_container_literal_block:
# Track the caption body separately
self.literal_block_caption = []
self.pushbody(self.literal_block_caption)
elif self.in_minipage and isinstance(node.parent, nodes.figure):
self.body.append('\\captionof{figure}{')
elif self.table and node.parent.tagname == 'figure':
self.body.append('\\sphinxfigcaption{')
else:
self.body.append('\\caption{')
def open(self):
self._open = True
self._col_specs = []
self.caption = []
self._attrs = {}
self._in_head = False # maybe context with search
def close(self):
self._open = False
self._col_specs = None
self.caption = []
self._attrs = {}
self.stubs = []
self.colwidths_auto = False
def get_latex_type(self):
if self._latex_type == 'longtable' and not self.caption:
# do not advance the "table" counter (requires "ltcaption" package)
return('longtable*')
return self._latex_type
def get_caption(self):
if not self.caption:
return ''
caption = ''.join(self.caption)
if 1 == self._translator.thead_depth():
return r'\caption{%s}\\' '\n' % caption
return r'\caption[]{%s (... continued)}\\' '\n' % caption
def visit_caption(self, node):
self.out.append('\n\\caption{')
def visit_target(self, node):
# Skip indirect targets:
if ('refuri' in node # external hyperlink
or 'refid' in node # resolved internal link
or 'refname' in node): # unresolved internal link
## self.out.append('%% %s\n' % node) # for debugging
return
self.out.append('%\n')
# do we need an anchor (\phantomsection)?
set_anchor = not(isinstance(node.parent, nodes.caption) or
isinstance(node.parent, nodes.title))
# TODO: where else can/must we omit the \phantomsection?
self.out += self.ids_to_labels(node, set_anchor)
def open(self):
self._open = True
self._col_specs = []
self.caption = []
self._attrs = {}
self._in_head = False # maybe context with search
def close(self):
self._open = False
self._col_specs = None
self.caption = []
self._attrs = {}
self.stubs = []
self.colwidths_auto = False
def get_latex_type(self):
if self._latex_type == 'longtable' and not self.caption:
# do not advance the "table" counter (requires "ltcaption" package)
return('longtable*')
return self._latex_type
def get_caption(self):
if not self.caption:
return ''
caption = ''.join(self.caption)
if 1 == self._translator.thead_depth():
return r'\caption{%s}\\' '\n' % caption
return r'\caption[]{%s (... continued)}\\' '\n' % caption
def visit_caption(self, node):
self.out.append('\n\\caption{')
def visit_target(self, node):
# Skip indirect targets:
if ('refuri' in node # external hyperlink
or 'refid' in node # resolved internal link
or 'refname' in node): # unresolved internal link
## self.out.append('%% %s\n' % node) # for debugging
return
self.out.append('%\n')
# do we need an anchor (\phantomsection)?
set_anchor = not(isinstance(node.parent, nodes.caption) or
isinstance(node.parent, nodes.title))
# TODO: where else can/must we omit the \phantomsection?
self.out += self.ids_to_labels(node, set_anchor)
def doctree_resolved(app, doctree, docname):
i = 1
figids = {}
for figure_info in doctree.traverse(figure):
if app.builder.name != 'latex' and app.config.number_figures:
for cap in figure_info.traverse(caption):
cap[0] = Text("%s %d: %s" % (app.config.figure_caption_prefix, i, cap[0]))
for id in figure_info['ids']:
figids[id] = i
i += 1
# replace numfig nodes with links
if app.builder.name != 'latex':
for ref_info in doctree.traverse(num_ref):
if '#' in ref_info['reftarget']:
label, target = ref_info['reftarget'].split('#')
labelfmt = label + " %d"
else:
labelfmt = '%d'
target = ref_info['reftarget']
if target not in figids:
continue
if app.builder.name == 'html':
target_doc = app.builder.env.figid_docname_map[target]
link = "%s#%s" % (app.builder.get_relative_uri(docname, target_doc),
target)
html = '<a class="pageref" href="%s">Fig. %s</a>' % (link, labelfmt %(figids[target]))
ref_info.replace_self(raw(html, html, format='html'))
else:
ref_info.replace_self(Text(labelfmt % (figids[target])))
def open(self):
self._open = True
self._col_specs = []
self.caption = []
self._attrs = {}
self._in_head = False # maybe context with search
def close(self):
self._open = False
self._col_specs = None
self.caption = []
self._attrs = {}
self.stubs = []
def get_latex_type(self):
if self._latex_type == 'longtable' and not self.caption:
# do not advance the "table" counter (requires "ltcaption" package)
return('longtable*')
return self._latex_type
def get_caption(self):
if not self.caption:
return ''
caption = ''.join(self.caption)
if 1 == self._translator.thead_depth():
return r'\caption{%s}\\' '\n' % caption
return r'\caption[]{%s (... continued)}\\' '\n' % caption
def visit_caption(self, node):
self.out.append('\n\\caption{')
def visit_target(self, node):
# Skip indirect targets:
if ('refuri' in node # external hyperlink
or 'refid' in node # resolved internal link
or 'refname' in node): # unresolved internal link
## self.out.append('%% %s\n' % node) # for debugging
return
self.out.append('%\n')
# do we need an anchor (\phantomsection)?
set_anchor = not(isinstance(node.parent, nodes.caption) or
isinstance(node.parent, nodes.title))
# TODO: where else can/must we omit the \phantomsection?
self.out += self.ids_to_labels(node, set_anchor)
def container_wrapper(directive, literal_node, caption):
container_node = nodes.container('', literal_block=True,
classes=['literal-block-wrapper'])
parsed = nodes.Element()
directive.state.nested_parse(ViewList([caption], source=''),
directive.content_offset, parsed)
caption_node = nodes.caption(parsed[0].rawsource, '',
*parsed[0].children)
caption_node.source = parsed[0].source
caption_node.line = parsed[0].line
container_node += caption_node
container_node += literal_node
return container_node
def run(self):
code = u'\n'.join(self.content)
linespec = self.options.get('emphasize-lines')
if linespec:
try:
nlines = len(self.content)
hl_lines = [x+1 for x in parselinenos(linespec, nlines)]
except ValueError as err:
document = self.state.document
return [document.reporter.warning(str(err), line=self.lineno)]
else:
hl_lines = None
if 'dedent' in self.options:
lines = code.split('\n')
lines = dedent_lines(lines, self.options['dedent'])
code = '\n'.join(lines)
literal = nodes.literal_block(code, code)
literal['language'] = self.arguments[0]
literal['linenos'] = 'linenos' in self.options or \
'lineno-start' in self.options
extra_args = literal['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']
set_source_info(self, literal)
caption = self.options.get('caption')
if caption:
self.options.setdefault('name', nodes.fully_normalize_name(caption))
literal = container_wrapper(self, literal, caption)
# literal will be note_implicit_target that is linked from caption and numref.
# when options['name'] is provided, it should be primary ID.
self.add_name(literal)
return [literal]
def figure_wrapper(directive, node, caption):
figure_node = nodes.figure('', node)
parsed = nodes.Element()
directive.state.nested_parse(ViewList([caption], source=''),
directive.content_offset, parsed)
caption_node = nodes.caption(parsed[0].rawsource, '',
*parsed[0].children)
caption_node.source = parsed[0].source
caption_node.line = parsed[0].line
figure_node += caption_node
return figure_node
def run(self):
if self.arguments:
document = self.state.document
if self.content:
return [document.reporter.warning(
'Graphviz directive cannot have both content and '
'a filename argument', line=self.lineno)]
env = self.state.document.settings.env
rel_filename, filename = env.relfn2path(self.arguments[0])
env.note_dependency(rel_filename)
try:
fp = codecs.open(filename, 'r', 'utf-8')
try:
dotcode = fp.read()
finally:
fp.close()
except (IOError, OSError):
return [document.reporter.warning(
'External Graphviz file %r not found or reading '
'it failed' % filename, line=self.lineno)]
else:
dotcode = '\n'.join(self.content)
if not dotcode.strip():
return [self.state_machine.reporter.warning(
'Ignoring "graphviz" directive without content.',
line=self.lineno)]
node = graphviz()
node['code'] = dotcode
node['options'] = []
if 'alt' in self.options:
node['alt'] = self.options['alt']
node['inline'] = 'inline' in self.options
caption = self.options.get('caption')
if caption and not node['inline']:
node = figure_wrapper(self, node, caption)
return [node]
def run(self):
node = graphviz()
node['code'] = '%s %s {\n%s\n}\n' % \
(self.name, self.arguments[0], '\n'.join(self.content))
node['options'] = []
if 'alt' in self.options:
node['alt'] = self.options['alt']
node['inline'] = 'inline' in self.options
caption = self.options.get('caption')
if caption and not node['inline']:
node = figure_wrapper(self, node, caption)
return [node]
def apply_source_workaround(node):
# workaround: nodes.term have wrong rawsource if classifier is specified.
# The behavior of docutils-0.11, 0.12 is:
# * when ``term text : classifier1 : classifier2`` is specified,
# * rawsource of term node will have: ``term text : classifier1 : classifier2``
# * rawsource of classifier node will be None
if isinstance(node, nodes.classifier) and not node.rawsource:
definition_list_item = node.parent
node.source = definition_list_item.source
node.line = definition_list_item.line - 1
node.rawsource = node.astext() # set 'classifier1' (or 'classifier2')
if isinstance(node, nodes.term):
# strip classifier from rawsource of term
for classifier in reversed(node.parent.traverse(nodes.classifier)):
node.rawsource = re.sub(
'\s*:\s*%s' % re.escape(classifier.astext()), '', node.rawsource)
# workaround: recommonmark-0.2.0 doesn't set rawsource attribute
if not node.rawsource:
node.rawsource = node.astext()
if node.source and node.rawsource:
return
# workaround: docutils-0.10.0 or older's nodes.caption for nodes.figure
# and nodes.title for nodes.admonition doesn't have source, line.
# this issue was filed to Docutils tracker:
# sf.net/tracker/?func=detail&aid=3599485&group_id=38414&atid=422032
# sourceforge.net/p/docutils/patches/108/
if (isinstance(node, (
nodes.caption,
nodes.title,
nodes.rubric,
nodes.line,
))):
node.source = find_source_node(node)
node.line = 0 # need fix docutils to get `node.line`
return