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.)
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
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.)
You cannot run
weave on the main package file because the
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.
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.
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
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
evaluated into functions.
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.
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.