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

Improvements to the tex rendering pipeline #362

Merged
merged 10 commits into from
Jun 14, 2020
82 changes: 49 additions & 33 deletions src/rendering/texformats.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@

abstract type TexFormat <: WeaveFormat end

set_rendering_options!(docformat::TexFormat; keep_unicode = false, kwargs...) = docformat.keep_unicode |= keep_unicode
function set_rendering_options!(docformat::TexFormat; keep_unicode = false, template=nothing, kwargs...)
docformat.keep_unicode |= keep_unicode
docformat.template = get_tex_template(template)
end

function formatfigures(chunk, docformat::TexFormat)
fignames = chunk.figures
Expand Down Expand Up @@ -73,40 +76,17 @@ function md_length_to_latex(def, reference)
return def
end

# plain Tex
# ---------

Base.@kwdef mutable struct Tex <: TexFormat
description = "Latex with custom code environments"
extension = "tex"
codestart = "\\begin{juliacode}"
codeend = "\\end{juliacode}"
termstart = "\\begin{juliaterm}"
termend = "\\end{juliaterm}"
outputstart = "\\begin{juliaout}"
outputend = "\\end{juliaout}"
mimetypes = ["application/pdf", "image/png", "text/latex", "text/plain"]
fig_ext = ".pdf"
out_width = "\\linewidth"
out_height = nothing
fig_pos = "htpb"
fig_env = "figure"
# specials
keep_unicode = false
end
register_format!("tex", Tex())

# minted Tex
# ----------

Base.@kwdef mutable struct TexMinted <: TexFormat
description = "Latex using minted for highlighting"
extension = "tex"
codestart = "\\begin{minted}[mathescape, fontsize=\\small, xleftmargin=0.5em]{julia}"
codestart = "\\begin{minted}[escapeinside=||, mathescape, fontsize=\\small, xleftmargin=0.5em]{julia}"
codeend = "\\end{minted}"
termstart = "\\begin{minted}[fontsize=\\footnotesize, xleftmargin=0.5em, mathescape]{jlcon}"
termstart = "\\begin{minted}[escapeinside=||, mathescape, fontsize=\\footnotesize, xleftmargin=0.5em]{jlcon}"
termend = "\\end{minted}"
outputstart = "\\begin{minted}[fontsize=\\small, xleftmargin=0.5em, mathescape, frame = leftline]{text}"
outputstart = "\\begin{minted}[escapeinside=||, mathescape, fontsize=\\small, xleftmargin=0.5em, frame = leftline]{text}"
outputend = "\\end{minted}"
mimetypes = ["application/pdf", "image/png", "text/latex", "text/plain"]
fig_ext = ".pdf"
Expand All @@ -116,6 +96,8 @@ Base.@kwdef mutable struct TexMinted <: TexFormat
fig_env = "figure"
# specials
keep_unicode = false
template = nothing
tex_deps = "\\usepackage{minted}"
end
register_format!("texminted", TexMinted())

Expand All @@ -142,6 +124,7 @@ Base.@kwdef mutable struct JMarkdown2tex <: TexFormat
highlight_theme = nothing
template = nothing
keep_unicode = false
tex_deps = ""
end
register_format!("md2tex", JMarkdown2tex())
register_format!("md2pdf", JMarkdown2tex())
Expand All @@ -155,17 +138,28 @@ end
get_tex_template(::Nothing) = get_template(normpath(TEMPLATE_DIR, "md2pdf.tpl"))
get_tex_template(x) = get_template(x)

function render_doc(docformat::TexFormat, body, doc)
return Mustache.render(
docformat.template;
body = body,
highlight = "",
tex_deps = docformat.tex_deps,
[Pair(Symbol(k), v) for (k, v) in doc.header]...,
)
end

function render_doc(docformat::JMarkdown2tex, body, doc)
return Mustache.render(
docformat.template;
body = body,
highlight = get_highlight_stylesheet(MIME("text/latex"), docformat.highlight_theme),
tex_deps = docformat.tex_deps,
[Pair(Symbol(k), v) for (k, v) in doc.header]...,
)
end

# very similar to export to html
function format_chunk(chunk::DocChunk, docformat::JMarkdown2tex)
function format_chunk(chunk::DocChunk, docformat::TexFormat)
out = IOBuffer()
io = IOBuffer()
for inline in chunk.content
Expand All @@ -182,7 +176,12 @@ function format_chunk(chunk::DocChunk, docformat::JMarkdown2tex)
end
clear_buffer_and_format!(io, out, WeaveMarkdown.latex)
out = take2string!(out)
return docformat.keep_unicode ? out : uc2tex(out)
return docformat.keep_unicode ? out : uc2tex(docformat, out)
end

function format_output(result, docformat::TexFormat)
Copy link
Member

Choose a reason for hiding this comment

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

I think this will produce "invalid" output texminted format, right ?
Hightlights.jl will include its own characters around some special characters e.g. _, so that it will result in weird output for minted output.
How about defining new format_output for TexMinted ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Well spotted. I hadn't figured this out.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed it.
However it did make my code have more duplicate lines again.

docformat.keep_unicode || return uc2tex(docformat, result, true)
return result
end

function format_output(result, docformat::JMarkdown2tex)
Expand All @@ -192,18 +191,22 @@ function format_output(result, docformat::JMarkdown2tex)
Highlights.Format.escape(io, MIME("text/latex"), x, charescape = true),
result,
)
docformat.keep_unicode || return uc2tex(result_escaped, true)
docformat.keep_unicode || return uc2tex(docformat, result_escaped, true)
return result_escaped
end

function format_code(code, docformat::TexFormat)
docformat.keep_unicode || return uc2tex(docformat, code, true)
return ret
end
function format_code(code, docformat::JMarkdown2tex)
ret = highlight_code(MIME("text/latex"), code, docformat.highlight_theme)
docformat.keep_unicode || return uc2tex(ret)
docformat.keep_unicode || return uc2tex(docformat, ret, false)
return ret
end

# Convert unicode to tex, escape listings if needed
function uc2tex(s, escape = false)
function uc2tex(::JMarkdown2tex, s, escape = false)
for key in keys(latex_symbols)
if escape
s = replace(s, latex_symbols[key] => "(*@\\ensuremath{$(texify(key))}@*)")
Expand All @@ -214,7 +217,20 @@ function uc2tex(s, escape = false)
return s
end

# should_render(chunk) ? highlight_term(MIME("text/latex"), , docformat.highlight_theme) : ""
function uc2tex(::TexFormat, s, escape = false)
for key in keys(latex_symbols)
if escape
s = replace(s, latex_symbols[key] => "|\$\\ensuremath{$(texify(key))}\$|")
else
s = replace(s, latex_symbols[key] => "\\ensuremath{$(texify(key))}")
end
end
return s
end
Copy link
Member

Choose a reason for hiding this comment

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

something like:

uc2tex(::JMarkdown2tex, s, escape = false) = unicode2tex(s, escape, "*@")
uc2tex(::TexFormat, s, escape = false) = unicode2tex(s, escape, "|\$")
function unicode2tex(s, escape, starter, closer = reverse(starter))
    for key in keys(latex_symbols)
        body = "\\ensuremath{$(texify(key))}"
        target = escape ? string(starter, body, closer) : body
        s = replace(s, latex_symbols[key] => body)
    end
    return s
end

would look more cleaner ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ah, that's much nicer !
Please put that instead 👍

Copy link
Member

Choose a reason for hiding this comment

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

or actually I don't think we can just define unicode2tex and don't use dispatch here; it only adds complexity here imho.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm sorry, I don't quite get what you are trying to say.

Copy link
Member

Choose a reason for hiding this comment

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

ups, sorry, very bad english, I tied to say:
I think we can just define unicode2tex and remove uc2tex. Using dispatches doesn't seem to be necessary here imho.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ah, I'm starting to understand.
The dispatch is indeed not necessary, but on the other hand, uc2tex is currently called 5 times and in one of those cases (

return docformat.keep_unicode ? out : uc2tex(docformat, out)
)

you can't hardcode the escape sequence. (Because the calling scope is used for all <:TexFormats.

There is however no real need for two names:

unicode2tex(::JMarkdown2tex, s, escape = false) = unicode2tex(s, escape, "*@")
unicode2tex(::TexMinted,     s, escape = false) = unicode2tex(s, escape, "|\$"))

function unicode2tex(s, escape, starter, closer = reverse(starter))
    for key in keys(latex_symbols)
        body = "\\ensuremath{$(texify(key))}"
        target = escape ? string(starter, body, closer) : body
        s = replace(s, latex_symbols[key] => body)
    end
    return s
end

Copy link
Contributor Author

Choose a reason for hiding this comment

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

alternatively escape and the escape sequence starter and closer could be made part of the JMarkdown2tex and TexMinted struct

Copy link
Member

Choose a reason for hiding this comment

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

sounds fair, I will like whichever way you would like to choose.


format_termchunk(chunk, docformat::TexFormat) =
string(docformat.termstart, chunk.output, docformat.termend, "\n")

format_termchunk(chunk, docformat::JMarkdown2tex) =
should_render(chunk) ? highlight_term(MIME("text/latex"), chunk.output, docformat.highlight_theme) : ""

Expand Down
4 changes: 3 additions & 1 deletion templates/md2pdf.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
\usepackage{graphicx}
\usepackage{microtype}
\usepackage{hyperref}

{{#:tex_deps}}
{{{ :tex_deps }}}
{{/:tex_deps}}
\setlength{\parindent}{0pt}
\setlength{\parskip}{1.2ex}

Expand Down