Skip to content
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

_repr_html_ and svg #5589

Closed
phwuil opened this issue Nov 5, 2018 · 11 comments · Fixed by #5610
Closed

_repr_html_ and svg #5589

phwuil opened this issue Nov 5, 2018 · 11 comments · Fixed by #5610

Comments

@phwuil
Copy link

@phwuil phwuil commented Nov 5, 2018

Hi,

Thanks for jupyterlab. I noticed that, with this code in a cell,

from IPython.display import display, SVG

class A:
    def __init__(self):
        print("init A")
        
    def _repr_html_(self):
        return """
<svg height="44pt" viewBox="0.00 0.00 62.00 44.00" width="62pt">
<g class="graph" id="graph0" transform="scale(1 1) rotate(0) translate(4 40)">
<g class="node" id="node1">
<title>a</title>
<g id="a_node1"><a xlink:title="(0) a">
<ellipse cx="27" cy="-18" fill="#444444" rx="27" ry="18" stroke="#000000"/>
<text fill="#ffffff" font-family="Times,serif" font-size="14.00" text-anchor="middle" x="27" y="-14.3">A</text>
</a>
</g>
</g>
</g>
</svg>
"""
    
a=A()
a

When executed in jupyter notebook : the svg (a black node with text "A") is shown in Out.
When executed in jupyterlab : No svg is displayed (No Out actually).

I tried with different type of html fragment (table, img) and I only found these different behaviours between jupyter notebook and jupyterlab for svg.

Is it a bug or is it a change between the 2 configurations ?

Thanks again !

python : 3.7.1
ipython : 7.1.1
jupyterlab : 0.35.4
notebook server: 5.7.0

@Madhu94
Copy link
Collaborator

@Madhu94 Madhu94 commented Nov 5, 2018

@phwuil Use _repr_svg_ display hook and not _repr_html_. The following seems to work for me -

class A:
    def __init__(self):
        print("init A")
        
    def _repr_svg_(self):
        return """
<svg xmlns="http://www.w3.org/2000/svg" height="44pt" viewBox="0.00 0.00 62.00 44.00" width="62pt">
<g class="graph" id="graph0" transform="scale(1 1) rotate(0) translate(4 40)">
<g class="node" id="node1">
<g id="a_node1"><title>A circle</title>
<ellipse cx="27" cy="-18" fill="#444444" rx="27" ry="18" stroke="#000000"/>
<text fill="#ffffff" font-family="Times,serif" font-size="14.00" text-anchor="middle" x="27" y="-14.3">A</text>

</g>
</g>
</g>
</svg>
"""
    
a=A()
a

@phwuil
Copy link
Author

@phwuil phwuil commented Nov 6, 2018

Thank you very much, Madhu94, for your answer !

I understand that I can use _repr_svg_ instead of _repr_html_ and it works nicely. thanks !

However I still have a different behaviour between notebooks and jupyterlab.

With this cell content :

from IPython.display import display, SVG, HTML
# result of a A._repr_svg_()
svg="""
<svg height="44pt" viewBox="0.00 0.00 62.00 44.00">
<g class="graph" id="graph0" transform="scale(1 1) rotate(0) translate(4 40)">
<title>G</title><g class="node" id="node1"><title>A</title><g id="a_node1">

<a xlink:title="(0) A">
    <ellipse cx="27" cy="-18" fill="#444444" rx="27" ry="18" stroke="#000000"/>
    <text fill="#ffffff" font-family="Times,serif" font-size="14.00" text-anchor="middle" x="27" y="-14.3">A</text>
</a>

</g></g></g></svg>

"""
display(HTML("<table><tr><td>"+svg+"</td><td>"+svg+"</td><td>"+svg+"</td></tr></table>"))

In jupyterlab, the (three same) nodes in the table are not visible whereas in jupyter notebook, they are. It looks like the problem comes from the anchor (<A>) in the svg.

Indee, with this cell :

from IPython.display import display, SVG, HTML
# result of a A._repr_svg_() without <A>
svg="""
<svg height="44pt" viewBox="0.00 0.00 62.00 44.00">
<g class="graph" id="graph0" transform="scale(1 1) rotate(0) translate(4 40)">
<title>G</title><g class="node" id="node1"><title>A</title><g id="a_node1">

    <ellipse cx="27" cy="-18" fill="#444444" rx="27" ry="18" stroke="#000000"/>
    <text fill="#ffffff" font-family="Times,serif" font-size="14.00" text-anchor="middle" x="27" y="-14.3">A</text>

</g></g></g></svg>

"""
display(HTML("<table><tr><td>"+svg+"</td><td>"+svg+"</td><td>"+svg+"</td></tr></table>"))

everything looks ok both in jupyterlab and in jupyter notebook.

Once again, is this a bug ?

@Madhu94
Copy link
Collaborator

@Madhu94 Madhu94 commented Nov 6, 2018

JupyterLab does try to do something with anchor tags' href attributes while rendering HTML, not SVG, but the notebook doesn't. The issue is that the anchor tag in HTML would be a string, but here it is an SVGAnimated string. That's why you use IPython.display.SVG or _repr_svg, everything works fine.

In my experience, lab tries to be "safer" :) than the notebook (like disabling inline JS), so you may not get exactly what you see in the notebook.

@Madhu94
Copy link
Collaborator

@Madhu94 Madhu94 commented Nov 6, 2018

Does that clears this up? Do you think this should behave differently?

@phwuil
Copy link
Author

@phwuil phwuil commented Nov 6, 2018

Hi again and thank for your comments.

I somehow understand the JupyterLab's concern (even if for SVGAnimated, it is a bit overreacted). However it is difficult to understand that when displaying HTML from a string containing a svg containing such an anchor tag, the correct behaviour is to silently display anything at all.

  • at best, the HTML and the svg could be displayed without the faulty SVGAnimated

  • at worst, an exception or a notification should be raised to explain the behaviour.

@Madhu94
Copy link
Collaborator

@Madhu94 Madhu94 commented Nov 6, 2018

at worst, an exception or a notification should be raised to explain the behaviour.

Yes, this seems fair. Let's wait for the maintainers to comment on this. I'm guessing for the moment you could just use the repr_svg hook.

@phwuil
Copy link
Author

@phwuil phwuil commented Nov 7, 2018

I'm guessing for the moment you could just use the repr_svg hook.

The svg I showed are generated by graphviz and I really need to be able to mix svg and HTML ...

screenshot_20181107_091424

where are displayed in a HTML table a svg, another HTML Table and a png image.. The 3 are generated by _repr_html_ for the 3 objects in line 1,2 and 3 of the cell [2]...

Then, for the moment, I will keep jupyter notebook as my primary target instead of jupyterlab and do not change anything in my code :-)

@Madhu94
Copy link
Collaborator

@Madhu94 Madhu94 commented Nov 10, 2018

This seems to be done intentionally - #4063 . @saulshanabrook The linked ticket mentions boxing css styles and using the context menu to save images. Are there other reasons for not supporting inline svgs ?

@saulshanabrook
Copy link
Member

@saulshanabrook saulshanabrook commented Nov 11, 2018

Hey @Madhu94 and @phwuil, thanks for bringing this to my attention. It looks like this is actually a bug, unrelated to that PR. When I try the example with the devtools open, I see an exception is raised:

screen shot 2018-11-10 at 8 21 24 pm

That's why nothing is rendered.

The issue is that we run some preprocessing on the HTML to change some link elements. And it is finding the a element in the SVG and thinking it is a normal link, but it is not.

I will open a PR shortly with a fix.

saulshanabrook added a commit that referenced this issue Nov 11, 2018
Fixes #5589 by skipping
processing of a elements that are not `HTMLAnchorElement`s, including
those within SVG elements. Currently, if you have a `a` element
inside an SVG element it will break HTML rendering since that element
does not have a `href` like other `a` elements do.
@Madhu94
Copy link
Collaborator

@Madhu94 Madhu94 commented Nov 11, 2018

Thanks @saulshanabrook , this one can be closed too - #5430. I think it is the same issue - attempting to lowercase the href of anchor tags

@phwuil
Copy link
Author

@phwuil phwuil commented Nov 13, 2018

cool and thanks !

@lock lock bot locked as resolved and limited conversation to collaborators Aug 8, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

3 participants