Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitdb0b215

Browse files
committed
Fix alt and caption handling in Sphinx directives
We currently template new reST to be re-parsed after the plot iscreated, but incorrectly copied the `alt` and `caption` values when theywere wrapped.Additionally, change `figmpl` to use Sphinx/docutils' tag creationfunctions. These functions correctly escape attributes and so fixesinvalid HTML when alt text contains quotes.
1 parent0b7a88a commitdb0b215

File tree

4 files changed

+53
-44
lines changed

4 files changed

+53
-44
lines changed

‎lib/matplotlib/sphinxext/figmpl_directive.py

Lines changed: 38 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,14 @@
1212
See the *FigureMpl* documentation below.
1313
1414
"""
15-
fromdocutilsimportnodes
16-
17-
fromdocutils.parsers.rstimportdirectives
18-
fromdocutils.parsers.rst.directives.imagesimportFigure,Image
19-
2015
importos
2116
fromos.pathimportrelpath
2217
frompathlibimportPurePath,Path
2318
importshutil
2419

20+
fromdocutilsimportnodes
21+
fromdocutils.parsers.rstimportdirectives
22+
fromdocutils.parsers.rst.directives.imagesimportFigure,Image
2523
fromsphinx.errorsimportExtensionError
2624

2725
importmatplotlib
@@ -193,12 +191,13 @@ def visit_figmpl_html(self, node):
193191
# make uri also be relative...
194192
nm=PurePath(node['uri'][1:]).name
195193
uri=f'{imagerel}/{rel}{nm}'
194+
img_attrs= {'src':uri,'alt':node['alt']}
196195

197196
# make srcset str. Need to change all the prefixes!
198197
maxsrc=uri
199-
srcsetst=''
200198
ifsrcset:
201199
maxmult=-1
200+
srcsetst=''
202201
formult,srcinsrcset.items():
203202
nm=PurePath(src[1:]).name
204203
# ../../_images/plot_1_2_0x.png
@@ -214,44 +213,43 @@ def visit_figmpl_html(self, node):
214213
maxsrc=path
215214

216215
# trim trailing comma and space...
217-
srcsetst=srcsetst[:-2]
216+
img_attrs['srcset']=srcsetst[:-2]
218217

219-
alt=node['alt']
220218
ifnode['class']isnotNone:
221-
classst=' '.join(node['class'])
222-
classst=f'class="{classst}"'
223-
224-
else:
225-
classst=''
226-
227-
stylers= ['width','height','scale']
228-
stylest=''
229-
forstyleinstylers:
219+
img_attrs['class']=' '.join(node['class'])
220+
forstylein ['width','height','scale']:
230221
ifnode[style]:
231-
stylest+=f'{style}:{node[style]};'
232-
233-
figalign=node['align']ifnode['align']else'center'
234-
235-
# <figure class="align-default" id="id1">
236-
# <a class="reference internal image-reference" href="_images/index-1.2x.png">
237-
# <img alt="_images/index-1.2x.png" src="_images/index-1.2x.png" style="width: 53%;" />
238-
# </a>
239-
# <figcaption>
240-
# <p><span class="caption-text">Figure caption is here....</span>
241-
# <a class="headerlink" href="#id1" title="Permalink to this image">#</a></p>
242-
# </figcaption>
243-
# </figure>
244-
img_block= (f'<img src="{uri}" style="{stylest}" srcset="{srcsetst}" '
245-
f'alt="{alt}"{classst}/>')
246-
html_block=f'<figure class="align-{figalign}">\n'
247-
html_block+=f' <a class="reference internal image-reference" href="{maxsrc}">\n'
248-
html_block+=f'{img_block}\n </a>\n'
222+
if'style'notinimg_attrs:
223+
img_attrs['style']=f'{style}:{node[style]};'
224+
else:
225+
img_attrs['style']+=f'{style}:{node[style]};'
226+
227+
# <figure class="align-default" id="id1">
228+
# <a class="reference internal image-reference" href="_images/index-1.2x.png">
229+
# <img alt="_images/index-1.2x.png"
230+
# src="_images/index-1.2x.png" style="width: 53%;" />
231+
# </a>
232+
# <figcaption>
233+
# <p><span class="caption-text">Figure caption is here....</span>
234+
# <a class="headerlink" href="#id1" title="Permalink to this image">#</a></p>
235+
# </figcaption>
236+
# </figure>
237+
self.body.append(
238+
self.starttag(
239+
node,'figure',
240+
CLASS=f'align-{node["align"]}'ifnode['align']else'align-center'))
241+
self.body.append(
242+
self.starttag(node,'a',CLASS='reference internal image-reference',
243+
href=maxsrc)+
244+
self.emptytag(node,'img',**img_attrs)+
245+
'</a>\n')
249246
ifnode['caption']:
250-
html_block+=' <figcaption>\n'
251-
html_block+=f' <p><span class="caption-text">{node["caption"]}</span></p>\n'
252-
html_block+=' </figcaption>\n'
253-
html_block+='</figure>\n'
254-
self.body.append(html_block)
247+
self.body.append(self.starttag(node,'figcaption'))
248+
self.body.append(self.starttag(node,'p'))
249+
self.body.append(self.starttag(node,'span',CLASS='caption-text'))
250+
self.body.append(node['caption'])
251+
self.body.append('</span></p></figcaption>\n')
252+
self.body.append('</figure>\n')
255253

256254

257255
defvisit_figmpl_latex(self,node):

‎lib/matplotlib/sphinxext/plot_directive.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -876,7 +876,7 @@ def run(arguments, content, options, state_machine, state, lineno):
876876

877877
# Properly indent the caption
878878
ifcaptionandconfig.plot_srcset:
879-
caption=f':caption:{caption}'
879+
caption=f':caption:{caption.replace("\n"," ")}'
880880
elifcaption:
881881
caption='\n'+'\n'.join(' '+line.strip()
882882
forlineincaption.split('\n'))
@@ -896,6 +896,9 @@ def run(arguments, content, options, state_machine, state, lineno):
896896
ifnofigs:
897897
images= []
898898

899+
if'alt'inoptions:
900+
options['alt']=options['alt'].replace('\n',' ')
901+
899902
opts= [
900903
f':{key}:{val}'forkey,valinoptions.items()
901904
ifkeyin ('alt','height','width','scale','align','class')]

‎lib/matplotlib/tests/test_sphinxext.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,11 @@ def plot_directive_file(num):
8383
assertfilecmp.cmp(range_6,img_dir/'range6_range6.png')
8484
# check if figure caption made it into html file
8585
assertb'This is the caption for plot 15.'inhtml_contents
86-
# check if figure caption using :caption: made it into html file
87-
assertb'Plot 17 uses the caption option.'inhtml_contents
86+
# check if figure caption using :caption: made it into html file (because this plot
87+
# doesn't use srcset, the caption preserves newlines in the output.)
88+
assertb'Plot 17 uses the caption option,\nwith multi-line input.'inhtml_contents
89+
# check if figure alt text using :alt: made it into html file
90+
assertb'Plot 17 uses the alt option, with multi-line input.'inhtml_contents
8891
# check if figure caption made it into html file
8992
assertb'This is the caption for plot 18.'inhtml_contents
9093
# check if the custom classes made it into the html file

‎lib/matplotlib/tests/tinypages/some_plots.rst

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,12 @@ Plot 16 uses a specific function in a file with plot commands:
135135
Plot 17 gets a caption specified by the:caption: option:
136136

137137
..plot::
138-
:caption: Plot 17 uses the caption option.
138+
:caption:
139+
Plot 17 uses the caption option,
140+
with multi-line input.
141+
:alt:
142+
Plot 17 uses the alt option,
143+
with multi-line input.
139144

140145
plt.figure()
141146
plt.plot(range(6))

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp