Is there a way to have different methods for Base.show, one for the REPL and another one only for showing a Widgets.Widget in Jupyter? For example:
module Foos
using Interact
export Foo, foo
struct Foo end
# This method is only for the REPL, that's good
Base.show(io::IO, ::Foo) = print(io, "This is a Foo")
function foo(::Foo)
@manipulate for x in 1:10
sin(x)
end
end
# How can i define this method in order
# use it only in Jypter notebooks?
function Base.show(io::IO, ???, x::Foo)
show(io, ???, foo(x))
end
end
For the REPL I can define Base.show(::IO, ::Foo), or also Base.show(::IO, MIME"text/plain", ::Foo) if necessary, but how can I show the foo function, which is a Widgets.Widget, in Jupyter? Is there a particular MIME that I have to use?
The question is, what is different about the display that you want to do in Jupyter compared to the text/plain output in the REPL? In the case of a Widget, I’m guessing that you want to use its text/html output method, so you would do:
Base.show(io::IO, m::MIME"text/html", x::Foo) = show(io, m, foo(x))
(In Jupyter, if both text/plain and text/html output are available, it shows the “richer” html output.)
This is for an image-like object. In the REPL I don’t have a way to display anything, but in a notebook I can display it and with a Widget I’d like to tweak brightness/contrast. This is for astronomical images which are usually unviewable without manually adjusting brightness/contrast
Thanks for your answer. I have a follow-up question on this:
I would like to “overload” the print function for a custom datatype.
There should be different outputs, depending on the available MIME, so plain text for REPL and HTML for jupyter notebook. Using display() I get the desired result. But calling print or show on my datatype, I just get the default output (here: Foo(“ABC”)).
So in a jupyter notebook it would look like this:
struct Foo
x::String
end
function Base.show(io::IO, m::MIME"text/plain", f::Foo)
print(io, "plain: $(f.x)")
end
function Base.show(io::IO, m::MIME"text/html", f::Foo)
print(io, "<p><strong>html: $(f.x)</strong></p>")
end
f = Foo("ABC")
html: ABC
print(f)
Foo(“ABC”)
show(f)
Foo(“ABC”)
display(f)
html: ABC
How do I get the formatted output when calling print(f)?
The print(x) function is always plain text. If you want formatted display, you either call display explicitly or you define an object that has a show method for a formatted type like HTML (which will be called when the object is evaluated in the REPL or Jupyter etc.)
For example, if you want the text/html version of f::Foo embedded in some other text/html output, you call show(io, "text/html", f) or repr("text/plain", f) as part of that output.
You can use the built-in HTML type to wrap an arbitrary HTML string in an object that will be displayed as formatted text in the browser (because the HTML object has a text/html method for show):
Thank you for your answer! But I’m afraid it did not yet solve my problem completely.
Below I have a MWE of what I’m trying to do:
struct MyType1
value::String
end
function Base.show(io::IO, m::MIME"text/html", f::MyType1)
print(io, """This is <strong>MyType1</strong> with value: <strong> $(f.value) </strong>""")
end
struct MyType2
value::MyType1
end
function Base.show(io::IO, m::MIME"text/html", f::MyType2)
print(io, """This is <strong>MyType2</strong> with value: """)
print(io, f.value)
end
m1 = MyType1("A")
m2 = MyType2(m1)
display(m1)
display(m2)
This results in:
This is MyType1 with value: A
This is MyType2 with value: MyType1(“A”)
But the result I would like to have is:
This is MyType1 with value: A
This is MyType2 with value: This is MyType1 with value: A
If I remove m::MIME"text/html" in Base.show of MyType1 :
function Base.show(io::IO, f::MyType1)
print(io, """This is MyType1 with value: <strong> $(f.value) </strong>""")
end
then I get the desired output. But then I couldn’t have a html and also a plain text version of show for MyType1. It seems I somehow need to to pass the MIME-type?
print always uses a text/plain representation. Instead, call show(io, m, f.value) at the point where you want to use the m::MIME representation f.value:
print(io, "This is <strong>MyType1</strong> with value: <strong> ")
show(io, m, f.value)
print(io, " </strong>")