Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

with_terminal to capture stdout and stdin #31

Merged
merged 12 commits into from
Sep 20, 2020
3 changes: 3 additions & 0 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ version = "0.6.1"
Base64 = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f"
Markdown = "d6f4376e-aef5-505a-96c1-9c027394607a"
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
Suppressor = "fd094767-a336-5f1f-9728-57cf17d0bbfb"

[compat]
julia = "^1"
Suppressor = "^0.2"

156 changes: 156 additions & 0 deletions src/CodeControl.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
export @with_stdout, @cond, @cond_with_stdout, @bind_cond, stdout_style, stdout_styles

"""
Dict containing predefined style sheets for `div.stdout`
"""
_predefined_css=Dict(

:default =>"""<style>
div.stdout {}
div.stdout pre {
color: #000;
border-radius: 1px;
background-color: #dfd;
border: 0px solid #ddd;
font-size: 65%;
}
</style>""",

:nowrap =>"""<style>
div.stdout {}
div.stdout pre {
color: #000;
border-radius: 1px;
background-color: #dfd;
border: 0px solid #ddd;
font-size: 65%;
word-break: normal !important;
word-wrap: normal !important;
white-space: pre !important;
overflow: auto;
}
</style>""",

:vintage =>"""<style>
div.stdout {}
div.stdout pre {
color: #2f2;
border-radius: 10px;
background-color: #333;
border: 5px solid #aaa;
font-size: 65%;
}
</style>""")

# Initialize with default css
_stdout_css=_predefined_css[:default]

"""
Set style sheet for output of stdout. Either one of
$(keys(_predefined_css)) or a string containing a css style sheet.
"""
function stdout_style(s)
global _stdout_css
if s in keys(_predefined_css)
_stdout_css=_predefined_css[s]
else
_stdout_css=s
end
end


"""
Return current stdout css style string
"""
stdout_style()=_stdout_css

"""
List predefined stdout css styles
"""
stdout_styles()=keys(_predefined_css)


"""
Wrap code output into HTML <pre> element.
"""
format_stdout(code_output)=HTML("""$(_stdout_css)<div class='stdout'><pre>"""*code_output*"""</pre></div>""")


"""
Run code, grab output from println, show etc and return it in a html string as <pre>.

Example:

````
@with_stdout begin
x=1+1
println(x)
end
````

"""
macro with_stdout(expr)
quote
format_stdout(Suppressor.@capture_out($(esc(expr))))
end
end


"""
Conditionally run code, grab output from println, show etc and return it in a html string as <pre>.

Example:

````
md"### Test Example \$(@bind test_example CheckBox(default=false))"

@with_stdout test_example begin
x=1+1
println(x)
end
````

"""
macro cond_with_stdout(run,expr)
# after an Idea of Benjamin Lungwitz
quote
if $(esc(run))
format_stdout(Suppressor.@capture_out($(esc(expr))))
end
end
end

"""
Conditionally run code

Example:

````
md"### Test Example \$(@bind test_example CheckBox(default=false))"

@cond test_example begin
x=1+1
end
````

"""
macro cond(run,expr)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why create a macro that does exactly the same as if? This makes code harder to understand

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is not exactly the same if I want to use this with a begin/end block.
I can have

@cond test @with_stdout  begin
     hack hack hack
end

but I must have

if test @with_stdout  begin
     hack hack hack
end end

with two ends at the end.
But I see some point in your remark (see above).

It comes down to finding the right usage patterns. I envision to explain to new uses the working of pluto before anything else and might explain things both ways. In this sense it appears to be more important to find a proper variable name instead of test than insisting on @cond.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this macro has 2 (small) advantages over if:

  1. it replaces both the if and the end, resulting in slightly less typing.
  2. it promotes code execution dependent on a checkbox (or any other bool) to an "official" Pluto usage pattern.

However, I agree that the benefit of it is not huge and therefore it is more a matter of taste. Alternatively, the if-pattern could be documented as officially recommended.

# after an Idea of Benjamin Lungwitz
quote
if $(esc(run))
$(esc(expr))
end
end
end


"""
Wanted:

Bind condition variable to checkbox and display it prefixed with label

Example:
````
@bind_cont test_example "### Test Example"
````
"""
2 changes: 2 additions & 0 deletions src/PlutoUI.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@ module PlutoUI

import Base: show, get
import Markdown: htmlesc, withtag
import Suppressor

const PKG_ROOT_DIR = normpath(joinpath(@__DIR__, ".."))

include("./Builtins.jl")
include("./Clock.jl")
include("./Resource.jl")
include("./CodeControl.jl")

end