我们从Python开源项目中,提取了以下49个代码示例,用于说明如何使用docutils.nodes.image()。
def make_thumbnail(self, imgfilename_inrst): """ Make thumbnail and return (html) path to image Parameters ---------- imgfilename_rst : rst Image filename (relative path), as it appears in the ReST file (coverted). """ builddir = self.env.app.outdir imgfilename_src = os.path.join(DOC_PATH, imgfilename_inrst) thumbfilename = self.thumbfilename(imgfilename_inrst) thumbfilename_inhtml = os.path.join('_images', thumbfilename) thumbfilename_dest = os.path.join(builddir, '_images', thumbfilename) im = Image.open(imgfilename_src) im.thumbnail(thumbnail_size) im.save(thumbfilename_dest) return thumbfilename_inhtml
def visit_reference(self, node): atts = {'class': 'reference'} if 'refuri' in node: atts['href'] = node['refuri'] if ( self.settings.cloak_email_addresses and atts['href'].startswith('mailto:')): atts['href'] = self.cloak_mailto(atts['href']) self.in_mailto = True atts['class'] += ' external' else: assert 'refid' in node, \ 'References must have "refuri" or "refid" attribute.' atts['href'] = '#' + node['refid'] atts['class'] += ' internal' if not isinstance(node.parent, nodes.TextElement): assert len(node) == 1 and isinstance(node[0], nodes.image) atts['class'] += ' image-reference' self.body.append(self.starttag(node, 'a', '', **atts))
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 post_process_images(self, doctree): """Pick the best candidate for all image URIs.""" for node in doctree.traverse(nodes.image): if '?' in node['candidates']: # don't rewrite nonlocal image URIs continue if '*' not in node['candidates']: for imgtype in self.supported_image_types: candidate = node['candidates'].get(imgtype, None) if candidate: break else: self.warn( 'no matching candidate for image URI %r' % node['uri'], '%s:%s' % (node.source, getattr(node, 'line', ''))) continue node['uri'] = candidate else: candidate = node['uri'] if candidate not in self.env.images: # non-existing URI; let it alone continue self.images[candidate] = self.env.images[candidate][1] # compile po methods
def post_process_images(self, doctree): """Pick the best candidate for an image and link down-scaled images to their high res version. """ Builder.post_process_images(self, doctree) if self.config.html_scaled_image_link: for node in doctree.traverse(nodes.image): scale_keys = ('scale', 'width', 'height') if not any((key in node) for key in scale_keys) or \ isinstance(node.parent, nodes.reference): # docutils does unfortunately not preserve the # ``target`` attribute on images, so we need to check # the parent node here. continue uri = node['uri'] reference = nodes.reference('', '', internal=True) if uri in self.images: reference['refuri'] = posixpath.join(self.imgpath, self.images[uri]) else: reference['refuri'] = uri node.replace_self(reference) reference.append(node)
def extract_messages(doctree): """Extract translatable messages from a document tree.""" for node in doctree.traverse(is_translatable): if isinstance(node, LITERAL_TYPE_NODES): msg = node.rawsource if not msg: msg = node.astext() elif isinstance(node, IMAGE_TYPE_NODES): msg = '.. image:: %s' % node['uri'] if node.get('alt'): msg += '\n :alt: %s' % node['alt'] else: msg = node.rawsource.replace('\n', ' ').strip() # XXX nodes rendering empty are likely a bug in sphinx.addnodes if msg: yield node, msg
def get_figtype(node): """Return figtype for given node.""" def has_child(node, cls): return any(isinstance(child, cls) for child in node) from docutils import nodes if isinstance(node, nodes.figure): return 'figure' elif isinstance(node, nodes.image) and isinstance(node.parent, nodes.figure): # bare image node is not supported because it doesn't have caption and # no-caption-target isn't a numbered figure. return 'figure' elif isinstance(node, nodes.table): return 'table' elif isinstance(node, nodes.container): if has_child(node, nodes.literal_block): return 'code-block' return None
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 get_image_node(self, source): file_name = self.name_source_snippet(source) file_path = os.path.join(VISUAL_EXAMPLES_DIR, file_name) env = self.state.document.settings.env if all([ render_snippet, env.config['render_examples'], not os.environ.get('SPHINX_DISABLE_RENDER', False), ]): try: render_snippet( source, file_path, output_dir=SOURCE_DIR, **self.options ) except: print("problematic code:\n%s" % source) raise img = nodes.image() img['uri'] = "/" + file_path return img
def notebook_to_rst(nbfilename): nbfilepath = os.path.join(EXPATH, nbfilename) rstfilename = get_rstfilename(nbfilename) output_files_dir = only_filename_no_ext(rstfilename) metadata_path = os.path.dirname(rstfilename) unique_key = nbfilename.rstrip('.ipynb') resources = { 'metadata': {'path': metadata_path}, 'output_files_dir': output_files_dir, # Prefix for the output image filenames 'unique_key': unique_key } # Read notebook with open(nbfilepath, 'r') as f: nb = nbformat.read(f, as_version=4) # Export exporter = nbsphinx.Exporter(execute='never', allow_errors=True) (body, resources) = exporter.from_notebook_node(nb, resources) # Correct path for the resources for filename in list(resources['outputs'].keys()): tmp = os.path.join(RST_PATH, filename) resources['outputs'][tmp] = resources['outputs'].pop(filename) fw = FilesWriter() fw.build_directory = RST_PATH # Prevent "not in doctree" complains resources['output_extension'] = '' body = 'Examples\n--------\n' + body fw.write(body, resources, notebook_name=rstfilename)
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 get_tokens(self, txtnodes): # A generator that yields ``(texttype, nodetext)`` tuples for a list # of "Text" nodes (interface to ``smartquotes.educate_tokens()``). texttype = {True: 'literal', # "literal" text is not changed: False: 'plain'} for txtnode in txtnodes: nodetype = texttype[isinstance(txtnode.parent, (nodes.literal, nodes.math, nodes.image, nodes.raw, nodes.problematic))] yield (nodetype, txtnode.astext())
def figwidth_value(argument): if argument.lower() == 'image': return 'image' else: return directives.length_or_percentage_or_unitless(argument, 'px')
def default_visit(self, node): if isinstance(node, (nodes.Text, nodes.image)): # direct text containers text = node.astext() # lineno seems to go backwards sometimes (?) self.lastlineno = lineno = max(get_lineno(node) or 0, self.lastlineno) seen = set() # don't report the same issue more than only once per line for match in detect_all(text): issue = match.group() line = extract_line(text, match.start()) if (issue, line) not in seen: self.builder.check_issue(line, lineno, issue) seen.add((issue, line))
def render_aafig_images(app, doctree): format_map = app.builder.config.aafig_format merge_dict(format_map, DEFAULT_FORMATS) if aafigure is None: app.builder.warn('aafigure module not installed, ASCII art images ' 'will be redered as literal text') for img in doctree.traverse(nodes.image): text = img.aafig['text'] if not hasattr(img, 'aafig'): continue if aafigure is None: img.replace_self(nodes.literal_block(text, text)) continue options = img.aafig['options'] _format = app.builder.format merge_dict(options, app.builder.config.aafig_default_options) if _format in format_map: options['format'] = format_map[_format] else: app.builder.warn('unsupported builder format "%s", please ' 'add a custom entry in aafig_format config option ' 'for this builder' % _format) img.replace_self(nodes.literal_block(text, text)) continue if options['format'] is None: img.replace_self(nodes.literal_block(text, text)) continue try: fname, _, _, extra = render_aafigure(app, text, options) except AafigError as exc: app.builder.warn('aafigure error: ' + str(exc)) img.replace_self(nodes.literal_block(text, text)) continue img['uri'] = fname # FIXME: find some way to avoid this hack in aafigure if extra: (width, height) = [x.split('"')[1] for x in extra.split()] if not img.has_key('width'): img['width'] = width if not img.has_key('height'): img['height'] = height
def __init__(self, app): self.env = app.env self.env.set_versioning_method(self.versioning_method, self.versioning_compare) self.srcdir = app.srcdir self.confdir = app.confdir self.outdir = app.outdir self.doctreedir = app.doctreedir if not path.isdir(self.doctreedir): os.makedirs(self.doctreedir) self.app = app self.warn = app.warn self.info = app.info self.config = app.config self.tags = app.tags self.tags.add(self.format) self.tags.add(self.name) self.tags.add("format_%s" % self.format) self.tags.add("builder_%s" % self.name) # compatibility aliases self.status_iterator = app.status_iterator self.old_status_iterator = app.old_status_iterator # images that need to be copied over (source -> dest) self.images = {} # basename of images directory self.imagedir = "" # relative path to image directory from current docname (used at writing docs) self.imgpath = "" # these get set later self.parallel_ok = False self.finish_tasks = None # load default translator class self.translator_class = app._translators.get(self.name) self.init() # helper methods
def copy_image_files(self): # copy image files if self.images: ensuredir(path.join(self.outdir, self.imagedir)) for src in self.app.status_iterator(self.images, 'copying images... ', brown, len(self.images)): dest = self.images[src] try: copyfile(path.join(self.srcdir, src), path.join(self.outdir, self.imagedir, dest)) except Exception as err: self.warn('cannot copy image file %r: %s' % (path.join(self.srcdir, src), err))
def clean_astext(node): """Like node.astext(), but ignore images.""" node = node.deepcopy() for img in node.traverse(nodes.image): img['alt'] = '' return node.astext()
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 visit_reference(self, node): atts = {'class': 'reference'} if node.get('internal') or 'refuri' not in node: atts['class'] += ' internal' else: atts['class'] += ' external' if 'refuri' in node: atts['href'] = node['refuri'] if self.settings.cloak_email_addresses and \ atts['href'].startswith('mailto:'): atts['href'] = self.cloak_mailto(atts['href']) self.in_mailto = 1 else: assert 'refid' in node, \ 'References must have "refuri" or "refid" attribute.' atts['href'] = '#' + node['refid'] if not isinstance(node.parent, nodes.TextElement): assert len(node) == 1 and isinstance(node[0], nodes.image) atts['class'] += ' image-reference' if 'reftitle' in node: atts['title'] = node['reftitle'] self.body.append(self.starttag(node, 'a', '', **atts)) if node.get('secnumber'): self.body.append(('%s' + self.secnumber_suffix) % '.'.join(map(str, node['secnumber'])))
def get_entries(self): def _get_sections(doctree): """ Return all sections after the 'Examples' section """ # Do not traverse all the sections, only look for those # that are siblings of the first node. ref_node = doctree[0][0] kwargs = dict(descend=False, siblings=True) exnode = None # Examples node for section in ref_node.traverse(nodes.section, **kwargs): if section[0].astext() == 'Examples': exnode = section break if not exnode: return for section in exnode[0].traverse(nodes.section, **kwargs): yield section for section in _get_sections(self.doctree): section_id = section.attributes['ids'][0] section_title = section[0].astext() # If an emphasis follows the section, it is the description if isinstance(section[1][0], nodes.emphasis): description = section[1][0].astext() else: description = '' # Last image in the section is used to create the thumbnail try: image_node = section.traverse(nodes.image)[-1] except IndexError: continue else: image_filename = image_node.attributes['uri'] yield GalleryEntry( title=section_title, section_id=section_id, html_link='{}#{}'.format(self.htmlfilename, section_id), thumbnail=self.make_thumbnail(image_filename), description=description)
def visit_title(self, node): parent = node.parent if isinstance(parent, addnodes.seealso): # the environment already handles this raise nodes.SkipNode elif self.this_is_the_title: if len(node.children) != 1 and not isinstance(node.children[0], nodes.Text): self.builder.warn('document title is not a single Text node', (self.curfilestack[-1], node.line)) if not self.elements['title']: # text needs to be escaped since it is inserted into # the output literally self.elements['title'] = node.astext().translate(tex_escape_map) self.this_is_the_title = 0 raise nodes.SkipNode elif isinstance(parent, nodes.section): short = '' if node.traverse(nodes.image): short = ('[%s]' % u' '.join(clean_astext(node).split()).translate(tex_escape_map)) try: self.body.append(r'\%s%s{' % (self.sectionnames[self.sectionlevel], short)) except IndexError: # just use "subparagraph", it's not numbered anyway self.body.append(r'\%s%s{' % (self.sectionnames[-1], short)) self.context.append('}\n') self.restrict_footnote(node) if self.next_section_ids: for id in sorted(self.next_section_ids): self.context[-1] += self.hypertarget(id, anchor=False) self.next_section_ids.clear() elif isinstance(parent, (nodes.topic, nodes.sidebar)): self.body.append(r'\textbf{') self.context.append('}\n\n\medskip\n\n') elif isinstance(parent, nodes.Admonition): self.body.append('{') self.context.append('}\n') elif isinstance(parent, nodes.table): # Redirect body output until title is finished. self.pushbody([]) else: self.builder.warn( 'encountered title node not in section, topic, table, ' 'admonition or sidebar', (self.curfilestack[-1], node.line or '')) self.body.append('\\textbf{') self.context.append('}\n') self.in_title = 1
def run(self): if 'align' in self.options: if isinstance(self.state, states.SubstitutionDef): # Check for align_v_values. if self.options['align'] not in self.align_v_values: raise self.error( 'Error in "%s" directive: "%s" is not a valid value ' 'for the "align" option within a substitution ' 'definition. Valid values for "align" are: "%s".' % (self.name, self.options['align'], '", "'.join(self.align_v_values))) elif self.options['align'] not in self.align_h_values: raise self.error( 'Error in "%s" directive: "%s" is not a valid value for ' 'the "align" option. Valid values for "align" are: "%s".' % (self.name, self.options['align'], '", "'.join(self.align_h_values))) messages = [] reference = directives.uri(self.arguments[0]) self.options['uri'] = reference reference_node = None if 'target' in self.options: block = states.escape2null( self.options['target']).splitlines() block = [line for line in block] target_type, data = self.state.parse_target( block, self.block_text, self.lineno) if target_type == 'refuri': reference_node = nodes.reference(refuri=data) elif target_type == 'refname': reference_node = nodes.reference( refname=fully_normalize_name(data), name=whitespace_normalize_name(data)) reference_node.indirect_reference_name = data self.state.document.note_refname(reference_node) else: # malformed target messages.append(data) # data is a system message del self.options['target'] set_classes(self.options) image_node = nodes.image(self.block_text, **self.options) self.add_name(image_node) if reference_node: reference_node += image_node return messages + [reference_node] else: return messages + [image_node]
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_title(self, node): parent = node.parent if isinstance(parent, addnodes.seealso): # the environment already handles this raise nodes.SkipNode elif self.this_is_the_title: if len(node.children) != 1 and not isinstance(node.children[0], nodes.Text): self.builder.warn('document title is not a single Text node', (self.curfilestack[-1], node.line)) if not self.elements['title']: # text needs to be escaped since it is inserted into # the output literally self.elements['title'] = node.astext().translate(tex_escape_map) self.this_is_the_title = 0 raise nodes.SkipNode elif isinstance(parent, nodes.section): short = '' if node.traverse(nodes.image): short = '[%s]' % ' '.join(clean_astext(node).split()).translate(tex_escape_map) try: self.body.append(r'\%s%s{' % (self.sectionnames[self.sectionlevel], short)) except IndexError: # just use "subparagraph", it's not numbered anyway self.body.append(r'\%s%s{' % (self.sectionnames[-1], short)) self.context.append('}\n') self.restrict_footnote(node) if self.next_section_ids: for id in self.next_section_ids: self.context[-1] += self.hypertarget(id, anchor=False) self.next_section_ids.clear() elif isinstance(parent, (nodes.topic, nodes.sidebar)): self.body.append(r'\textbf{') self.context.append('}\n\n\medskip\n\n') elif isinstance(parent, nodes.Admonition): self.body.append('{') self.context.append('}\n') elif isinstance(parent, nodes.table): # Redirect body output until title is finished. self.pushbody([]) else: self.builder.warn( 'encountered title node not in section, topic, table, ' 'admonition or sidebar', (self.curfilestack[-1], node.line or '')) self.body.append('\\textbf{') self.context.append('}\n') self.in_title = 1
def visit_image(self, node): olduri = node['uri'] # rewrite the URI if the environment knows about it if olduri in self.builder.images: node['uri'] = posixpath.join(self.builder.imgpath, self.builder.images[olduri]) if node['uri'].lower().endswith('svg') or \ node['uri'].lower().endswith('svgz'): atts = {'src': node['uri']} if 'width' in node: atts['width'] = node['width'] if 'height' in node: atts['height'] = node['height'] if 'alt' in node: atts['alt'] = node['alt'] if 'align' in node: self.body.append('<div align="%s" class="align-%s">' % (node['align'], node['align'])) self.context.append('</div>\n') else: self.context.append('') self.body.append(self.emptytag(node, 'img', '', **atts)) return if 'scale' in node: # Try to figure out image height and width. Docutils does that too, # but it tries the final file name, which does not necessarily exist # yet at the time the HTML file is written. if Image and not ('width' in node and 'height' in node): try: im = Image.open(os.path.join(self.builder.srcdir, olduri)) except (IOError, # Source image can't be found or opened UnicodeError): # PIL doesn't like Unicode paths. pass else: if 'width' not in node: node['width'] = str(im.size[0]) if 'height' not in node: node['height'] = str(im.size[1]) try: im.fp.close() except Exception: pass BaseTranslator.visit_image(self, node)
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.request.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]