Note that the handling of subdirectories is different than that used by the sphinx
figure directive::
.. figure-mpl:: plot_directive/nestedpage/index-1.png
:alt: bar
:srcset: plot_directive/nestedpage/index-1.png
plot_directive/nestedpage/index-1.2x.png 2.00x
:class: plot_directive
The resulting html (at ``nestedpage/index.html``)::
where the subdirectory is included in the image name for uniqueness.
"""
has_content = False
required_arguments = 1
optional_arguments = 2
final_argument_whitespace = False
option_spec = {
'alt': directives.unchanged,
'height': directives.length_or_unitless,
'width': directives.length_or_percentage_or_unitless,
'scale': directives.nonnegative_int,
'align': Image.align,
'class': directives.class_option,
'caption': directives.unchanged,
'srcset': directives.unchanged,
}
def run(self):
image_node = figmplnode()
imagenm = self.arguments[0]
image_node['alt'] = self.options.get('alt', '')
image_node['align'] = self.options.get('align', None)
image_node['class'] = self.options.get('class', None)
image_node['width'] = self.options.get('width', None)
image_node['height'] = self.options.get('height', None)
image_node['scale'] = self.options.get('scale', None)
image_node['caption'] = self.options.get('caption', None)
# we would like uri to be the highest dpi version so that
# latex etc will use that. But for now, lets just make
# imagenm... maybe pdf one day?
image_node['uri'] = imagenm
image_node['srcset'] = self.options.get('srcset', None)
return [image_node]
def _parse_srcsetNodes(st):
"""
parse srcset...
"""
entries = st.split(',')
srcset = {}
for entry in entries:
spl = entry.strip().split(' ')
if len(spl) == 1:
srcset[0] = spl[0]
elif len(spl) == 2:
mult = spl[1][:-1]
srcset[float(mult)] = spl[0]
else:
raise ExtensionError(f'srcset argument "{entry}" is invalid.')
return srcset
def _copy_images_figmpl(self, node):
# these will be the temporary place the plot-directive put the images eg:
# ../../../build/html/plot_directive/users/explain/artists/index-1.png
if node['srcset']:
srcset = _parse_srcsetNodes(node['srcset'])
else:
srcset = None
# the rst file's location: eg /Users/username/matplotlib/doc/users/explain/artists
docsource = PurePath(self.document['source']).parent
# get the relpath relative to root:
srctop = self.builder.srcdir
rel = relpath(docsource, srctop).replace('.', '').replace(os.sep, '-')
if len(rel):
rel += '-'
# eg: users/explain/artists
imagedir = PurePath(self.builder.outdir, self.builder.imagedir)
# eg: /Users/username/matplotlib/doc/build/html/_images/users/explain/artists
Path(imagedir).mkdir(parents=True, exist_ok=True)
# copy all the sources to the imagedir:
if srcset:
for src in srcset.values():
# the entries in srcset are relative to docsource's directory
abspath = PurePath(docsource, src)
name = rel + abspath.name
shutil.copyfile(abspath, imagedir / name)
else:
abspath = PurePath(docsource, node['uri'])
name = rel + abspath.name
shutil.copyfile(abspath, imagedir / name)
return imagedir, srcset, rel
def visit_figmpl_html(self, node):
imagedir, srcset, rel = _copy_images_figmpl(self, node)
# /doc/examples/subd/plot_1.rst
docsource = PurePath(self.document['source'])
# /doc/
# make sure to add the trailing slash:
srctop = PurePath(self.builder.srcdir, '')
# examples/subd/plot_1.rst
relsource = relpath(docsource, srctop)
# /doc/build/html
desttop = PurePath(self.builder.outdir, '')
# /doc/build/html/examples/subd
dest = desttop / relsource
# ../../_images/ for dirhtml and ../_images/ for html
imagerel = PurePath(relpath(imagedir, dest.parent)).as_posix()
if self.builder.name == "dirhtml":
imagerel = f'..{imagerel}'
# make uri also be relative...
nm = PurePath(node['uri'][1:]).name
uri = f'{imagerel}/{rel}{nm}'
# make srcset str. Need to change all the prefixes!
maxsrc = uri
srcsetst = ''
if srcset:
maxmult = -1
for mult, src in srcset.items():
nm = PurePath(src[1:]).name
# ../../_images/plot_1_2_0x.png
path = f'{imagerel}/{rel}{nm}'
srcsetst += path
if mult == 0:
srcsetst += ', '
else:
srcsetst += f' {mult:1.2f}x, '
if mult > maxmult:
maxmult = mult
maxsrc = path
# trim trailing comma and space...
srcsetst = srcsetst[:-2]
alt = node['alt']
if node['class'] is not None:
classst = ' '.join(node['class'])
classst = f'class="{classst}"'
else:
classst = ''
stylers = ['width', 'height', 'scale']
stylest = ''
for style in stylers:
if node[style]:
stylest += f'{style}: {node[style]};'
figalign = node['align'] if node['align'] else 'center'
#
#
# Figure caption is here.... # #
#{node["caption"]}
\n' html_block += '