我们从Python开源项目中,提取了以下47个代码示例,用于说明如何使用docutils.nodes.figure()。
def latex_image_length(self, width_str, figure=False): """Convert `width_str` with rst length to LaTeX length. This function is copied from docutils' latex writer The last parameter, ``figure`` is only for compatibility with 1.4.4. It will be removed at Sphinx-1.5. """ match = re.match('(\d*\.?\d*)\s*(\S*)', width_str) if not match: # fallback return width_str res = width_str amount, unit = match.groups()[:2] if figure and unit in ('', 'pt'): res = '%sbp' % amount # convert to 'bp' elif not unit or unit == "px": # pixels: let LaTeX alone return None elif unit == "%": res = "%.3f\\linewidth" % (float(amount) / 100.0) return res
def visit_footnote(self, node): try: backref = node['backrefs'][0] except IndexError: backref = node['ids'][0] # no backref, use self-ref instead if self.settings.figure_footnotes: self.requirements['~fnt_floats'] = PreambleCmds.footnote_floats self.out.append('\\begin{figure}[b]') self.append_hypertargets(node) if node.get('id') == node.get('name'): # explicite label self.out += self.ids_to_labels(node) elif self.docutils_footnotes: self.fallbacks['footnotes'] = PreambleCmds.footnotes num,text = node.astext().split(None,1) if self.settings.footnote_references == 'brackets': num = '[%s]' % num self.out.append('%%\n\\DUfootnotetext{%s}{%s}{%s}{' % (node['ids'][0], backref, self.encode(num))) if node['ids'] == node['names']: self.out += self.ids_to_labels(node) # mask newline to prevent spurious whitespace: self.out.append('%') ## else: # TODO: "real" LaTeX \footnote{}s
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)
def depart_caption(self, node): self.body.append('</span>') # append permalink if available if isinstance(node.parent, nodes.container) and node.parent.get('literal_block'): self.add_permalink_ref(node.parent, _('Permalink to this code')) elif isinstance(node.parent, nodes.figure): image_nodes = node.parent.traverse(nodes.image) target_node = image_nodes and image_nodes[0] or node.parent self.add_permalink_ref(target_node, _('Permalink to this image')) elif node.parent.get('toctree'): self.add_permalink_ref(node.parent.parent, _('Permalink to this toctree')) if isinstance(node.parent, nodes.container) and node.parent.get('literal_block'): self.body.append('</div>\n') else: BaseTranslator.depart_caption(self, node)
def depart_image(self, node): if type(node.parent) == nodes.figure: self.visit_reference(node) self.append('[' + node.attributes.get('alt', 'Image') + ']') self.depart_reference(node) self.newline() else: self.append('[' + node.attributes.get('alt', 'Image') + ']')
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 visit_citation(self, node): # TODO maybe use cite bibitems if self._use_latex_citations: self.push_output_collector([]) else: # TODO: do we need these? ## self.requirements['~fnt_floats'] = PreambleCmds.footnote_floats self.out.append(r'\begin{figure}[b]') self.append_hypertargets(node)
def depart_citation(self, node): if self._use_latex_citations: label = self.out[0] text = ''.join(self.out[1:]) self._bibitems.append([label, text]) self.pop_output_collector() else: self.out.append('\\end{figure}\n')
def visit_figure(self, node): self.requirements['float_settings'] = PreambleCmds.float_settings # The 'align' attribute sets the "outer alignment", # for "inner alignment" use LaTeX default alignment (similar to HTML) alignment = node.attributes.get('align', 'center') if alignment != 'center': # The LaTeX "figure" environment always uses the full linewidth, # so "outer alignment" is ignored. Just write a comment. # TODO: use the wrapfigure environment? self.out.append('\n\\begin{figure} %% align = "%s"\n' % alignment) else: self.out.append('\n\\begin{figure}\n') if node.get('ids'): self.out += self.ids_to_labels(node) + ['\n']
def depart_figure(self, node): self.out.append('\\end{figure}\n')
def visit_figure(self, node): self.requirements['float_settings'] = PreambleCmds.float_settings self.duclass_open(node) # The 'align' attribute sets the "outer alignment", # for "inner alignment" use LaTeX default alignment (similar to HTML) alignment = node.attributes.get('align', 'center') if alignment != 'center': # The LaTeX "figure" environment always uses the full linewidth, # so "outer alignment" is ignored. Just write a comment. # TODO: use the wrapfigure environment? self.out.append('\\begin{figure} %% align = "%s"\n' % alignment) else: self.out.append('\\begin{figure}\n') if node.get('ids'): self.out += self.ids_to_labels(node) + ['\n']
def depart_figure(self, node): self.out.append('\\end{figure}\n') self.duclass_close(node)
def get_figtype(self, node): """Get figure type of nodes.""" def has_child(node, cls): return any(isinstance(child, cls) for child in node) if isinstance(node, nodes.container): if node.get('literal_block') and has_child(node, nodes.literal_block): return 'code-block' else: return None else: figtype, _ = self.enumerable_nodes.get(node.__class__, (None, None)) return figtype
def doctree_read(app, doctree): # first generate figure numbers for each figure env = app.builder.env figid_docname_map = getattr(env, 'figid_docname_map', {}) for figure_info in doctree.traverse(figure): for id in figure_info['ids']: figid_docname_map[id] = env.docname env.figid_docname_map = figid_docname_map
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 visit_figure(self, node): self.requirements['float_settings'] = PreambleCmds.float_settings # The 'align' attribute sets the "outer alignment", # for "inner alignment" use LaTeX default alignment (similar to HTML) alignment = node.attributes.get('align', 'center') if alignment != 'center': # The LaTeX "figure" environment always uses the full textwidth, # so "outer alignment" is ignored. Just write a comment. # TODO: use the wrapfigure environment? self.out.append('\n\\begin{figure} %% align = "%s"\n' % alignment) else: self.out.append('\n\\begin{figure}\n') if node.get('ids'): self.out += self.ids_to_labels(node) + ['\n']
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 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
def depart_caption(self, node): if (isinstance(node.parent, nodes.figure) or (isinstance(node.parent, nodes.container) and node.parent.get('literal_block'))): self.body.append('}\n')
def visit_figure(self, node): ids = '' for id in self.next_figure_ids: ids += self.hypertarget(id, anchor=False) self.next_figure_ids.clear() self.restrict_footnote(node) 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) if 'width' in node and node.get('align', '') in ('left', 'right'): self.body.append('\\begin{wrapfigure}{%s}{%s}\n\\centering' % (node['align'] == 'right' and 'r' or 'l', node['width'])) self.context.append(ids + '\\end{wrapfigure}\n') else: if ('align' not in node.attributes or node.attributes['align'] == 'center'): # centering does not add vertical space like center. align = '\n\\centering' align_end = '' else: # TODO non vertical space for other alignments. align = '\\begin{flush%s}' % node.attributes['align'] align_end = '\\end{flush%s}' % node.attributes['align'] self.body.append('\\begin{figure}[%s]%s\n' % ( self.elements['figure_align'], align)) if any(isinstance(child, nodes.caption) for child in node): self.body.append('\\capstart\n') self.context.append(ids + align_end + '\\end{figure}\n')
def figure_wrapper(directive, node, caption): # type: (Directive, nodes.Node, unicode) -> nodes.figure figure_node = nodes.figure('', node) if 'align' in node: figure_node['align'] = node.attributes.pop('align') 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 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">%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 visit_target(self, node): def add_target(id): # indexing uses standard LaTeX index markup, so the targets # will be generated differently if id.startswith('index-'): return # do not generate \phantomsection in \section{} anchor = not self.in_title self.body.append(self.hypertarget(id, anchor=anchor)) # postpone the labels until after the sectioning command parindex = node.parent.index(node) try: try: next = node.parent[parindex+1] except IndexError: # last node in parent, look at next after parent # (for section of equal level) if it exists if node.parent.parent is not None: next = node.parent.parent[ node.parent.parent.index(node.parent)] else: raise if isinstance(next, nodes.section): if node.get('refid'): self.next_section_ids.add(node['refid']) self.next_section_ids.update(node['ids']) return else: domain = self.builder.env.domains['std'] figtype = domain.get_figtype(next) if figtype and domain.get_numfig_title(next): ids = set() # labels for figures go in the figure body, not before if node.get('refid'): ids.add(node['refid']) ids.update(node['ids']) self.push_hyperlink_ids(figtype, ids) return except IndexError: pass if 'refuri' in node: return if node.get('refid'): add_target(node['refid']) for id in sorted(node['ids']): add_target(id)
def visit_image(self, node): self.requirements['graphicx'] = self.graphicx_package attrs = node.attributes # Convert image URI to a local file path imagepath = urllib.url2pathname(attrs['uri']).replace('\\', '/') # alignment defaults: if not 'align' in attrs: # Set default align of image in a figure to 'center' if isinstance(node.parent, nodes.figure): attrs['align'] = 'center' # query 'align-*' class argument for cls in node['classes']: if cls.startswith('align-'): attrs['align'] = cls.split('-')[1] # pre- and postfix (prefix inserted in reverse order) pre = [] post = [] include_graphics_options = [] align_codes = { # inline images: by default latex aligns the bottom. 'bottom': ('', ''), 'middle': (r'\raisebox{-0.5\height}{', '}'), 'top': (r'\raisebox{-\height}{', '}'), # block level images: 'center': (r'\noindent\makebox[\linewidth][c]{', '}'), 'left': (r'\noindent{', r'\hfill}'), 'right': (r'\noindent{\hfill', '}'),} if 'align' in attrs: # TODO: warn or ignore non-applicable alignment settings? try: align_code = align_codes[attrs['align']] pre.append(align_code[0]) post.append(align_code[1]) except KeyError: pass # TODO: warn? if 'height' in attrs: include_graphics_options.append('height=%s' % self.to_latex_length(attrs['height'])) if 'scale' in attrs: include_graphics_options.append('scale=%f' % (attrs['scale'] / 100.0)) if 'width' in attrs: include_graphics_options.append('width=%s' % self.to_latex_length(attrs['width'])) if not (self.is_inline(node) or isinstance(node.parent, nodes.figure)): pre.append('\n') post.append('\n') pre.reverse() self.out.extend(pre) options = '' if include_graphics_options: options = '[%s]' % (','.join(include_graphics_options)) self.out.append('\\includegraphics%s{%s}' % (options, imagepath)) self.out.extend(post)
def visit_image(self, node): self.requirements['graphicx'] = self.graphicx_package attrs = node.attributes # Convert image URI to a local file path imagepath = urllib.url2pathname(attrs['uri']).replace('\\', '/') # alignment defaults: if not 'align' in attrs: # Set default align of image in a figure to 'center' if isinstance(node.parent, nodes.figure): attrs['align'] = 'center' self.set_align_from_classes(node) # pre- and postfix (prefix inserted in reverse order) pre = [] post = [] include_graphics_options = [] align_codes = { # inline images: by default latex aligns the bottom. 'bottom': ('', ''), 'middle': (r'\raisebox{-0.5\height}{', '}'), 'top': (r'\raisebox{-\height}{', '}'), # block level images: 'center': (r'\noindent\makebox[\linewidth][c]{', '}'), 'left': (r'\noindent{', r'\hfill}'), 'right': (r'\noindent{\hfill', '}'),} if 'align' in attrs: # TODO: warn or ignore non-applicable alignment settings? try: align_code = align_codes[attrs['align']] pre.append(align_code[0]) post.append(align_code[1]) except KeyError: pass # TODO: warn? if 'height' in attrs: include_graphics_options.append('height=%s' % self.to_latex_length(attrs['height'])) if 'scale' in attrs: include_graphics_options.append('scale=%f' % (attrs['scale'] / 100.0)) if 'width' in attrs: include_graphics_options.append('width=%s' % self.to_latex_length(attrs['width'])) if not (self.is_inline(node) or isinstance(node.parent, (nodes.figure, nodes.compound))): pre.append('\n') if not (self.is_inline(node) or isinstance(node.parent, nodes.figure)): post.append('\n') pre.reverse() self.out.extend(pre) options = '' if include_graphics_options: options = '[%s]' % (','.join(include_graphics_options)) self.out.append('\\includegraphics%s{%s}' % (options, imagepath)) self.out.extend(post)
def visit_image(self, node): self.requirements['graphicx'] = self.graphicx_package attrs = node.attributes # Convert image URI to a local file path imagepath = urllib.url2pathname(attrs['uri']).replace('\\', '/') # alignment defaults: if not 'align' in attrs: # Set default align of image in a figure to 'center' if isinstance(node.parent, nodes.figure): attrs['align'] = 'center' # query 'align-*' class argument for cls in node['classes']: if cls.startswith('align-'): attrs['align'] = cls.split('-')[1] # pre- and postfix (prefix inserted in reverse order) pre = [] post = [] include_graphics_options = [] align_codes = { # inline images: by default latex aligns the bottom. 'bottom': ('', ''), 'middle': (r'\raisebox{-0.5\height}{', '}'), 'top': (r'\raisebox{-\height}{', '}'), # block level images: 'center': (r'\noindent\makebox[\textwidth][c]{', '}'), 'left': (r'\noindent{', r'\hfill}'), 'right': (r'\noindent{\hfill', '}'),} if 'align' in attrs: # TODO: warn or ignore non-applicable alignment settings? try: align_code = align_codes[attrs['align']] pre.append(align_code[0]) post.append(align_code[1]) except KeyError: pass # TODO: warn? if 'height' in attrs: include_graphics_options.append('height=%s' % self.to_latex_length(attrs['height'])) if 'scale' in attrs: include_graphics_options.append('scale=%f' % (attrs['scale'] / 100.0)) if 'width' in attrs: include_graphics_options.append('width=%s' % self.to_latex_length(attrs['width'])) if not (self.is_inline(node) or isinstance(node.parent, nodes.figure)): pre.append('\n') post.append('\n') pre.reverse() self.out.extend(pre) options = '' if include_graphics_options: options = '[%s]' % (','.join(include_graphics_options)) self.out.append('\\includegraphics%s{%s}' % (options, imagepath)) self.out.extend(post)
def run(self): figwidth = self.options.pop('figwidth', None) figclasses = self.options.pop('figclass', None) align = self.options.pop('align', None) (image_node,) = Image.run(self) if isinstance(image_node, nodes.system_message): return [image_node] figure_node = nodes.figure('', image_node) if figwidth == 'image': if PIL and self.state.document.settings.file_insertion_enabled: imagepath = urllib.url2pathname(image_node['uri']) try: img = PIL.Image.open( imagepath.encode(sys.getfilesystemencoding())) except (IOError, UnicodeEncodeError): pass # TODO: warn? else: self.state.document.settings.record_dependencies.add( imagepath.replace('\\', '/')) figure_node['width'] = '%dpx' % img.size[0] del img elif figwidth is not None: figure_node['width'] = figwidth if figclasses: figure_node['classes'] += figclasses if align: figure_node['align'] = align if self.content: node = nodes.Element() # anonymous container for parsing self.state.nested_parse(self.content, self.content_offset, node) first_node = node[0] if isinstance(first_node, nodes.paragraph): caption = nodes.caption(first_node.rawsource, '', *first_node.children) caption.source = first_node.source caption.line = first_node.line figure_node += caption elif not (isinstance(first_node, nodes.comment) and len(first_node) == 0): error = self.state_machine.reporter.error( 'Figure caption must be a paragraph or empty comment.', nodes.literal_block(self.block_text, self.block_text), line=self.lineno) return [figure_node, error] if len(node) > 1: figure_node += nodes.legend('', *node[1:]) return [figure_node]
def visit_target(self, node): def add_target(id): # indexing uses standard LaTeX index markup, so the targets # will be generated differently if id.startswith('index-'): return # do not generate \phantomsection in \section{} anchor = not self.in_title self.body.append(self.hypertarget(id, anchor=anchor)) # postpone the labels until after the sectioning command parindex = node.parent.index(node) try: try: next = node.parent[parindex+1] except IndexError: # last node in parent, look at next after parent # (for section of equal level) if it exists if node.parent.parent is not None: next = node.parent.parent[ node.parent.parent.index(node.parent)] else: raise if isinstance(next, nodes.section): if node.get('refid'): self.next_section_ids.add(node['refid']) self.next_section_ids.update(node['ids']) return elif isinstance(next, nodes.figure): # labels for figures go in the figure body, not before if node.get('refid'): self.next_figure_ids.add(node['refid']) self.next_figure_ids.update(node['ids']) return elif isinstance(next, nodes.table): # same for tables, but only if they have a caption for n in next: if isinstance(n, nodes.title): if node.get('refid'): 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: return if node.get('refid'): add_target(node['refid']) for id in node['ids']: add_target(id)