using Markdown ## override HTML esc of strings Markdown.htmlinline(io::IO, md::AbstractString) = write(io, md) Base.show(io::IO, ::MIME"text/qmd", content) = Markdown.plain(io, content) ## Hacky way to set *global* values for rendering ## Expects title to be very first thing in a jmd file ## Proper way would be to use https://quarto.org/docs/extensions/nbfilter.html function inject_code(io::IO) println(io, """ {{< include ../_common_code.qmd >}} """) end # println(io, """ # ```{julia} # #| echo: false # import Logging # Logging.disable_logging(Logging.Info) # or e.g. Logging.Info # Logging.disable_logging(Logging.Warn) # import SymPy # function Base.show(io::IO, ::MIME"text/html", x::T) where {T <: SymPy.SymbolicObject} # println(io, " ") # println(io, "\\\\[") # println(io, sympy.latex(x)) # println(io, "\\\\]") # println(io, "") # 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 # nothing # ``` # """) # end ## Main function to take a jmd file and turn into an HTML function markdownToHTML(fname::AbstractString; TITLE="", kwargs...) dirnm, basenm = dirname(fname), basename(fname) newnm = replace(fname, r"[.].*" => ".html") out = jmd2qmd(fname; TITLE=TITLE, kwargs...) io = open(newnm, "w") write(io, out) close(io) end """ jmd2qmd(io, jmd_file) Convert `.jmd` file in `jmd_file` to a `.qmd` file, write output to `io`. ## Rationale `.jmd` files have a slightly different Markdown syntax than expected by `.qmd` files. In particular: * code blocks use comments at the top of the file to add features like `echo=false` * admonitions use "callout" syntax * LaTeX uses dollar signs for delimiters, not double back tics or a `math` block """ function jmd2qmd(io::IO, jmd_file::AbstractString) out = Markdown.parse_file(jmd_file, flavor=Markdown.julia) for (i,content) in enumerate(out.content) i == 2 && inject_code(io) ## requires title to be *first* if isa(out.content[i], Markdown.Code) txt = content.code lang = content.language langs = filter(x -> length(x) > 0, (lstrip ∘ rstrip).(split(lang, ";"))) if length(langs) > 0 flavor = popfirst!(langs) println(io, "```{$flavor}") for option ∈ langs k, v = split(option, "=") println(io, "#| $k: $v") end println(io, txt) println(io, "```") else println(io, "```") println(io, txt) println(io, "```") end elseif isa(content, Markdown.LaTeX) println(io, '$', '$') println(io, content.formula) print(io, '$', '$') println(io) elseif isa(content, Markdown.Admonition) category = content.category if !(category ∈ ("note", "warning", "important", "tip", "caution")) category = "note" end println(io, ":::{.callout-$category}") println(io, "## $(content.title)") show(io, MIME("text/qmd"), content.content) println(io, "") println(io, ":::") else ## we drill down #Markdown.html(io, content) #show(io, MIME("text/qmd"), content) Markdown.plain(io, content) println(io, "") end println(io, "") end end