-
Notifications
You must be signed in to change notification settings - Fork 207
Bugfix thumbnail text formatting #1005
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Bugfix thumbnail text formatting #1005
Conversation
sphinx_gallery/gen_rst.py
Outdated
# :term:`the term` --> the term | ||
string = re.sub(r':term:`(.*)`', r'\1', string) | ||
# :ref:`the ref` --> the ref | ||
string = re.sub(r':ref:`(.*)`', r'\1', string) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are many possible roles here, so perhaps we want something more like
# :term:`the term` --> the term | |
string = re.sub(r':term:`(.*)`', r'\1', string) | |
# :ref:`the ref` --> the ref | |
string = re.sub(r':ref:`(.*)`', r'\1', string) | |
# :role:`the thing` --> the thing | |
string = re.sub(r':[a-z]+:`([^`]+)`', r'\1', string) |
Note the generalization of the :role:
and also the exclusion of any backticks within the captured group -- otherwise something like this would probably be an issue because regex is greedy:
:meth:`a.B` and :meth:`a.C`
I think would collapse to something bad like:
a.b` and :meth:`a.C
As another issue, people can also do
:meth:`My method <a.B>`
but we could deal with that later/in another PR unless you're keen to work on more regex :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually I think this works:
:[a-z]+:`([^`<>]+)( <[^`<>]+>)?`
On https://regex101.com/ it replaces
:meth:`MyMethod <a.B>` and :meth:`a.C`
with
MyMethod and a.C
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh yes, that's much better :) I added it!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think it's a good idea to implement a (subset of a) docutils parser by hand. Why not use existing code? Doesn't Sphinx have some functionality like this?
As a concrete example what can go wrong when doing it manually: did you know that the role name can also be used as a suffix?
https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html#interpreted-text
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed it would be good to use something built in if we can.
In the meantime I'd rather not let the perfect be the enemy of the good here. In years of looking through intersphinx refs I've seen hundreds or thousands of prefixes and no postfixes. It's not saying they don't exist, but again, perfect being the enemy of the good... I'd assume YAGNI on trying to catch every variant here if we do indeed need to start with our own parsing.
And I'm okay with merging this imperfect/manual version as-is, with a follow-up PR to improve it. This already improves on what we have I think.
sphinx_gallery/tests/test_full.py
Outdated
# check used and unused | ||
if has_graphviz: | ||
assert 'alt="API unused entries graph"' in content | ||
if sphinx_app.config.sphinx_gallery_conf['show_api_usage']: | ||
assert 'alt="sphinx_gallery usage graph"' in content | ||
else: | ||
assert 'alt="sphinx_gallery usage graph"' not in content | ||
# check graph output | ||
assert 'src="_images/graphviz-' in content | ||
else: | ||
assert 'alt="API unused entries graph"' not in content | ||
assert 'alt="sphinx_gallery usage graph"' not in content |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These used to check that the correct images were there. Instead of deleting these lines (presumably because the alt
is gone?), could you look for correct file names instead?
sphinx_gallery/gen_rst.py
Outdated
# *string* --> string | ||
string = re.sub(r'\*([^\*]*)\*', r'\1', string) | ||
# `link text <url>`_ --> link text | ||
string = re.sub(r'`(.*) <.*>`\_', r'\1', string) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will also need adjustments like
[^`<>]+
instead of the .*
inside the group, similar to below
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
... and links can be anonymous with two trailing underscores, so maybe
string = re.sub(r'`(.*) <.*>`\_', r'\1', string) | |
string = re.sub(r'`([^`<>]+) <[^`<>]>`\_\_?', r'\1', string) |
Isn't regex fun? 😆 |
@@ -265,7 +265,7 @@ def identify_names(script_blocks, global_variables=None, node=''): | |||
.. only:: html | |||
|
|||
.. image:: /{thumbnail} | |||
:alt: {title} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I might have missed this but why are we removing the alt?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since the current alt is simply the gallery item's title, #998 suggested to remove it because redundant information will be spoken when using a screen reader 🙂
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be nice to check the title is still read out?
@@ -21,7 +21,7 @@ | |||
.. only:: html | |||
|
|||
.. image:: /fake_dir/images/thumb/sphx_glr_test_file_thumb.png | |||
:alt: test title | |||
:alt: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not remove the :alt:
altogether if we are not using it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Strictly speaking, the alt
is required:
https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/alt#value
Practically speaking, it makes a big difference for screen readers (AFAIK, but I'm not really a user myself): with alt=""
, the image is ignored by screen readers, without the alt
attribute, the screen reader will try to provide some information, maybe the file name of the image, which really wouldn't be very helpful.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay this still seems like a regression -- the alt
seems important for screen readers.
@alexisthual WDYT about keeping it, but setting the display: None
for the alt in our CSS? That would remove the visual redundancy on mouseover, but keep screen readers working, right?
But as a Sphinx extension you can generate arbitrary HTML, right? |
One reason is that I think way more people understand and can work with reST markup than can work with docutils nodes. In this sense sticking with reST is perhaps more maintainable. But if someone with docutils expertise and experience can come up with a better and still maintainable/understandable solution that would be great! |
README.rst
Outdated
in a proper conda environment: | ||
|
||
``` | ||
pip install -r requirements.txt -r dev-requirements.txt |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't that (partially) redundant to what was mentioned above in the section "Install as a Sphinx-Gallery developer"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just noticed this one and agree -- will push a commit to fix
I gave this PR some more thoughts and effort. It's not trivial to replace links generated by Moreover, I'm afraid that changing all this HTML/CSS could eventually break of lot of things (especially if we don't generate the exact same URLs). I won't have that much bandwidth to work on this in the coming weeks, and I think @mgeier wanted this to be merged soon, but I feel like we need to get this right the first time or it could have dramatic effects haha 😄 |
@alexisthual should we merge this as is to remove the redundancy for now at least then, or no? |
So far, this PR:
I think it could use one last review, but otherwise it's probably good to go! Besides, changing the HTML/CSS structure of thumbnails would be useful, but I don't have the bandwidth now to test these changes thoroughly. I'm not saying it's not doable though, and maybe someone more used to |
Thanks for the update @alexisthual!
I'm not in a hurry at all. I prefer a good solution to a fast solution. I agree that the current state of this PR is a nice incremental improvement, and as far as I'm concerned there's nothing speaking against merging it (except for my comment above about the documentation: #1005 (comment)). However, I think the generated HTML is still awkward and bloated, and most of the CSS is for working around that awkwardness. Regarding the implementation in So if Sphinx Gallery produces nice HTML and lean CSS, I'm happy to keep compatibility in |
FYI: I'm currently working on spatialaudio/nbsphinx#706, which uses custom HTML/CSS and does not use Sphinx Gallery anymore. CSS comparisonSphinx Gallery: .sphx-glr-thumbnails {
width: 100%;
margin: 0px 0px 20px 0px;
/* align thumbnails on a grid */
justify-content: space-between;
display: grid;
/* each grid column should be at least 160px (this will determine
the actual number of columns) and then take as much of the
remaining width as possible */
grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
gap: 15px;
}
.sphx-glr-thumbnails .toctree-wrapper {
/* hide empty toctree divs added to the DOM
by sphinx even though the toctree is hidden
(they would fill grid places with empty divs) */
display: none;
}
.sphx-glr-thumbcontainer {
background: transparent;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
border-radius: 5px;
box-shadow: 0 0 10px var(--sg-thumb-box-shadow-color);
/* useful to absolutely position link in div */
position: relative;
/* thumbnail width should include padding and borders
and take all available space */
box-sizing: border-box;
width: 100%;
padding: 10px;
border: 1px solid transparent;
/* align content in thumbnail */
display: flex;
flex-direction: column;
align-items: center;
gap: 7px;
}
.sphx-glr-thumbcontainer p {
position: absolute;
top: 0;
left: 0;
}
.sphx-glr-thumbcontainer p,
.sphx-glr-thumbcontainer p a {
/* link should cover the whole thumbnail div */
width: 100%;
height: 100%;
}
.sphx-glr-thumbcontainer p a span {
/* text within link should be masked
(we are just interested in the href) */
display: none;
}
.sphx-glr-thumbcontainer:hover {
border: 1px solid;
border-color: var(--sg-thumb-hover-border);
cursor: pointer;
}
.sphx-glr-thumbcontainer a.internal {
bottom: 0;
display: block;
left: 0;
box-sizing: border-box;
padding: 150px 10px 0;
position: absolute;
right: 0;
top: 0;
}
/* Next one is to avoid Sphinx traditional theme to cover all the
thumbnail with its default link Background color */
.sphx-glr-thumbcontainer a.internal:hover {
background-color: transparent;
}
.sphx-glr-thumbcontainer p {
margin: 0 0 0.1em 0;
}
.sphx-glr-thumbcontainer .figure {
margin: 10px;
width: 160px;
}
.sphx-glr-thumbcontainer img {
display: inline;
max-height: 112px;
max-width: 160px;
}
.sphx-glr-thumbcontainer[tooltip]:hover:after {
background: var(--sg-tooltip-background);
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
color: var(--sg-tooltip-foreground);
content: attr(tooltip);
padding: 10px;
z-index: 98;
width: 100%;
height: 100%;
position: absolute;
pointer-events: none;
top: 0;
box-sizing: border-box;
overflow: hidden;
backdrop-filter: blur(3px);
} proposed for .nbsphinx-gallery {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
gap: 10px;
margin-top: 1em;
margin-bottom: 1em;
}
.nbsphinx-gallery > a {
padding: 5px;
border: 1px dotted currentColor;
border-radius: 2px;
text-align: center;
}
.nbsphinx-gallery > a:hover {
border-style: solid;
}
.nbsphinx-gallery img {
max-width: 100%;
max-height: 100%;
}
.nbsphinx-gallery > a > div:first-child {
display: flex;
align-items: start;
justify-content: center;
height: 120px;
margin-bottom: 5px;
} |
Sounds like alt-as-blank is the way to go here since the contents are elsewhere / redundant for screen readers. I'll fix the conflict and mark for merge when green, then cut 0.12 |
Sphinx Gallery 0.11.0 left RST formatting characters in the thumbnail titles. This was fixed in version 0.12.2 for most cases by github.com/sphinx-gallery/sphinx-gallery/pull/1005, which doesn't cover default roles. So to restore the previous behavior we need to explicitely a role.
Closes #1002 and #998.
Regarding the unsanitized text, I saw in
gen_rst.py
that:I checked thumbnail tooltips from
nilearn
andmne-python
to add some missing cases to the sanitizing function. I think this PR, at least partially, now fixes both issues, but feel free to add more cases to the sanitizing function!Regarding the "redundant title", @mgeier I agree with you that we can get rid of the uninformative
<img />
alt description, so I did it in this PR.However, I don't have much control over the rest of the thumbnail: the
<p><a><span>...</span></a></p>
is here for the sole purpose of having the thumbnail behave like an HTML link. As it's handled bysphinx
I don't think I can customize its output, which is the reason why it is hidden. Eventually, the<div class="sphx-glr-thumbnail-title">...</div>
is needed to display the title properly.