```{julia}
#| output: false
#| echo: false

## Formatting options are included here; not in CalculusWithJulia.WeaveSupport
using QuizQuestions
nothing
```

```{julia}
#| output: false
#| echo: false
fig_size=(800, 600)
nothing
```

```{julia}
#| output: false
#| echo: false

import Logging
Logging.disable_logging(Logging.Info) # or e.g. Logging.Info
Logging.disable_logging(Logging.Warn)
nothing
```

```{julia}
#| eval: false
#| echo: false
import SymPy
function Base.show(io::IO, ::MIME"text/html", x::T) where {T <: SymPy.SymbolicObject}
    println(io, "<span class=\"math-left-align\" style=\"padding-left: 4px; width:0; float:left;\"> ")
    println(io, "\\[")
    println(io, sympy.latex(x))
    println(io, "\\]")
    println(io, "</span>")
end

```

```{julia}
#| output: false
#| echo: false
# ImageFile
## WeaveSupport from CalculusWithJulia package
## moved here to lighten up CwJ package
import Base64: base64encode
import Markdown
using Mustache
using Tables

# q and L
using LaTeXStrings
macro q_str(x)
    "`$x`"
end

"""

Take an image file and encode it

## Examples

ImageFile("http://...", "caption")
ImageFile("/fullpath/to_file/", "caption")
ImageFile(:integrals, "figures/pic.png", "caption")
ImageFile(p, "caption") # p a Plot object



"""
mutable struct ImageFile
    f
    caption
    alt
    width
    content
end
# 2 args f, caption
ImageFile(f,caption=""; alt="A Figure", width=nothing) = ImageFile(f, caption, alt, width)

# 3 args dir, f, caption
function ImageFile(dir::Symbol, f::AbstractString, caption;
                   alt="A Figure", width=nothing)


    basedir = replace(dirname(@__DIR__), "/src" => "")
    #fname = joinpath(basedir, "CwJ", string(dir), f)
    fname = joinpath(basedir, string(dir), f)

    ImageFile(fname, caption, alt, width)
end
# plot -> string for file
function ImageFile(f, caption, alt, width)
    imgfile = tempname() * ".gif"
    io = open(imgfile, "w")
    show(io, "image/png", f)
    close(io)
    ImageFile(imgfile, caption, alt, width)
end

gif_to_img_tpl = Mustache.mt"""
  <img src="data:image/gif;base64,{{{:data}}}" class="card-img-top" alt="{{{:alt}}}">
"""


function ImageFile(f::AbstractString, caption, alt, width)
    fcontent = occursin(r"^http", f) ? read(download(f), String) : read(f, String)
    data = base64encode(fcontent)
    content = Mustache.render(gif_to_img_tpl, data=data, alt=alt)
    ImageFile(f, caption, alt, width, content)
end


function Base.show(io::IO, m::MIME"text/html", x::ImageFile)
    content = x.content
    if content == nothing
        data = (read(x.f, String))
        content = gif_to_image(data=data, alt="figure")
    end
    caption = (Markdown.html ∘ Markdown.parse)(x.caption)
    print(io, """<div class="d-flex justify-content-center">""")
    print(io, "  <figure>")
    print(io, content)
    print(io, "    <figcaption>")
    print(io, caption)
    print(io, """
    </figcaption>
  </figure>
</div>
""")
end

import TextWrap
function Base.show(io::IO, m::MIME"text/plain", x::ImageFile)

    caption = (TextWrap.wrap ∘ Markdown.plain ∘ Markdown.parse)(x.caption)
    println(io, """
---------------------------------
|
|     see online version for    |
|           image               |
|                               |
--------------------------------
""")
    println(io, caption)
    return nothing
end



# hack to work around issue
# import Markdown
# import CalculusWithJulia
# function CalculusWithJulia.WeaveSupport.ImageFile(d::Symbol, f::AbstractString, caption; kwargs...)
#     nm = joinpath("..", string(d), f)
#     u = "![$caption]($nm)"
#     Markdown.parse(u)
# end



# Table
#| echo: false
#https://github.com/TheRoniOne/MDTable.jl/blob/master/src/write.jl
function MDTable(io::IO, df)
    rows = Tables.rows(df)
    sch = Tables.schema(rows)
    names = Tables.columnnames(rows)
    header = true

    headers::String = ""
    for i in 1:length(names)
        if i != length(names)
            headers = headers * "| $(names[i]) "
        else
            headers = headers * "| $(names[i]) " * "|\n"
        end
    end
    print(io, headers)

    println(io, "| --- " ^ length(names) * "|")
    for row in rows
        line::String = ""
        Tables.eachcolumn(sch, row) do val, i, nm
            print(io, "| ", chomp(string(val)))
        end
        println(io, "|")
    end
end
Table(d) = Markdown.parse(sprint(io -> MDTable(io, d)))
table(d) = Table(d)

# HTMLoutput
struct HTMLoutput
    x
    centered::Bool
    caption::String
    HTMLoutput(x; centered::Bool=false, caption::String="") = new(x, centered, caption)
end
function Base.show(io::IO, ::MIME"text/html", x::HTMLoutput)
    if !x.centered
        txt = x.x
    else
        centered_content_tpl = """
<div class="d-flex justify-content-center">
<div class="card border-light mx-3 px-3 my-3 py-3" style="{{#:width}}width={{:width}}px{{/:width}}{{^:width}} max-width: 560px;{{/:width}}">
  {{{:content}}}
  <div class="card-footer text-muted">
      {{{:caption}}}
  </div>
</div>
</div>
"""
        txt = Mustache.render(centered_content_tpl; content=x.x, caption=x.caption)
    end
    print(io, txt)
end

function Base.show(io::IO, m::MIME"text/plain", x::HTMLoutput)

    caption = (TextWrap.wrap ∘ Markdown.plain ∘ Markdown.parse)(x.caption)
    println(io, "Content available in online version")
    println(io, caption)
    return nothing
end

nothing
```
