Summary
I was able to achieve my goal. The resultant package is here. The functions and constants defined in the package are available for use by typing using KM620
. The PDF outputs are generated by typing ]test KM620
. (You must have XeLaTeX installed.)
Approach
Function Definitions
Getting one-liner function definitions rendered to PDF was actually straightforward with Weave.jl and Latexify.jl. Just write @latexrun
in front of the function definition and mark a new weave chunk on the line above it with #'
. Then weave(inputfile, doctype="md2pdf", out_path=outputfile)
will do all the work for you. I put this weave command in my test/runtests.jl
file, so I have an easy way to update the PDFs whenever I update the function definitions. (I still may look for a better way to force the PDFs to update periodically.)
File Structure
You cannot run weave
on the main package file because the module
and end #module
keywords will not work with Weave’s idea of code chunks. Instead I structured the main file as below and called weave
on the included files.
module KM620
include("KM620_equations.jl")
include("KM620_tables.jl")
end # module KM620
You will also need to repeat the using Latexify, LaTeXStrings
line at the top of each of these included files because the weaved files must be self-contained.
Contant Definitions
If your constants have simple types, then you can use @latexdefine
in the same manner as @latexrun
was used for functions definitions above. Unfortunately, DataFrames cannot be rendered to PDF this way.
The issue with @latexdefine
is that it expects things to have a :raw
representation (because it does something akin to "\$x = $(latexify(x; env=:raw))\$"
). DataFrames don’t have this, but only “latexify” as latexify(df; env=:mdtable)
.
I also ran into an error when trying to use const df = DataFrame(<stuff>)
and latexify(df)
in the same file. The file would weave the PDF fine, but it would break on the latexify
line when trying to using
the package. To get around this error, I moved the latexify
lines to their own file in the test folder and weaved that file instead of the package file. This test file will using KM620
so the constants are defined before latexifying them.
Note that this method of latexifying after defining will not work for function definitions because the alphanumeric representation of the function is not saved with the function. It is only available for latexification at the time when the function definition is run. I worked around this limitation somewhat to display equations inside my DataFrame by defining expressions which I later eval
uated into functions.
Markdown Notes
Markdown notes can be written and rendered to PDF anywhere using markdown syntax on the #'
commented lines. I rendered a separate Nomenclature PDF alongside the others using this method.
Weave vs. Literate
I originally tried using Literate.jl, but this was a dead end. The LaTeX strings were just displayed in markdown code blocks rather than actually being rendered. This issue led me to Weave. I also came across LiterateWeave.jl that could potentially be useful, but I did not dive into it.
Final Thoughts
My package is in a working state now, but probably not an optimized state. I am open to suggestions on how to do this better. I just wanted to leave some lessons learned for anyone else who happens across this post and to link my package for others to use as a template for this sort of thing.