Open philchalmers opened 3 weeks ago
Related to #57, the equation Michael was presenting can now be constructed using the following dev/printEqn.R
, which follows a similar presentation format as sprintf()
but for latexMatrix
, matrix
, and character
vector substitutions flagged with an %
symbol. So the original
C <- latexMatrix(matrix(c(0,1,1,0), nrow=1), matrix = "bmatrix")
B <- latexMatrix('\\beta', ncol = 3, nrow=4, comma=TRUE, prefix.col = 'y_')
B0 <- latexMatrix('\\beta', ncol = 3, nrow=2, comma=TRUE, prefix.col = 'y_')
with the presentation construction
Eqn("\\mathcal{H}_0 : \\mathbf{C} \\mathbf{B} & = ",
C, B,
Eqn_newline(), Eqn_newline(),
'&\n',
B0,
"= \\mathbf{0}_{(2 \\times 3)}",
align=TRUE)
can now be presented with the structure first + substitutions
printEqn("*H*_0 : **C B** & = %C %B \\\\
& = %B0 = **0**_{(2 `*` 3)}",
list(C=C, B=B, B0=B0), `**`='mathbf', align=TRUE)
Or, even more simply if boldsymbol
is sufficient (default for **
wrapper) and the objects C
, B
, and B0
are available in the parent frame, then
printEqn("*H*_0 : **C B** & = %C %B \\\\
& = %B0 = **0**_{(2 `*` 3)}", align=TRUE)
I personally find these much more readable and easier to modify.
That looks very interesting indeed, but I'll have to study it some more to get a better sense of what can be done with this.
Just to complete Phil's example (perhaps for the vignette):
A <- latexMatrix("a", 2, 2) B <- latexMatrix("b", 2, 2) kronecker(A, B) # Generate the 'definition' of Kronecker product, Bmat <- latexMatrix('\\mathbf{B}', ncol=1, nrow=1) kronecker(A, Bmat) Eqn("\\mathbf{A} \\otimes \\mathbf{B} = &", kronecker(A, Bmat), "\\\\[1.5ex]\n= & ", kronecker(A, B), align = TRUE)
For future posterity, here's how printEqn()
would look for the Kronecker example:
A <- latexMatrix("a", 2, 2)
B <- latexMatrix("b", 2, 2)
kronecker(A, B) |> Eqn()
# Generate the 'definition' of Kronecker product,
Bmat <- latexMatrix('\\mathbf{B}', ncol=1, nrow=1)
KABmat <- kronecker(A, Bmat)
KAB <- kronecker(A, B)
Eqn("\\mathbf{A} \\otimes \\mathbf{B} = &",
KABmat,
"\\\\[1.5ex]\n= & ",
KAB,
align = TRUE)
source(here::here('dev', 'printEqn.R'))
printEqn("**A** \\otimes **B** = & %KABmat \\\\[1.5ex]
= & %KAB", align=TRUE)
With the new partition.R
, which is always fun with Kronecker products.
A <- latexMatrix("a", 2, 2)
B <- latexMatrix("b", 2, 2)
# Generate the 'definition' of Kronecker product,
Bmat <- latexMatrix('\\mathbf{B}', ncol=1, nrow=1)
source(here::here('dev', 'partition.R'))
source(here::here('dev', 'printEqn.R'))
KABmat <- kronecker(A, Bmat) |> partition(rows=1, columns=1)
KAB <- kronecker(A, B) |> partition(rows=2, columns=2)
printEqn("**A** \\otimes **B** = & %KABmat \\\\[1.5ex]
= & %KAB", align=TRUE)
The last of which gives
EDIT: uploaded wrong jpg.
In the examples above, we use Eqn_newline()
, but also "\\\\[1.5ex]
where it's desired to add some extra space.
Could Eqn_newline()
gain a vspace=
argument for this purpose?
Added. Eqn_newline(1.5)
now gives the desired output, though the metric
can be changed as well.
Quarto support added for equations by adding Eqn(, quarto=TRUE)
, but AFAICS there's no way to include ref()
as the quarto compiler seems to treat @ instances at different points in the complication. Equations can still be referenced via @eq-myeqn
in the usual Quarto way, but not in the inline {r}
chunks. Slightly more awkward, but I suppose if one if going the Quarto route then this is a minimal inconvenience as the HTML and PDF outputs use the same format.
Great! Hope you don't mind if I tweak the documentation a bit.
Took some digging, but I finally found a way to make quarto behave well with ref()
, which now gives the same behavior as the other methods. I'm looking into a more automated way to detect the CLI type similar to knitr::is_html_output()
, but the best I've found so far is quarto::is_using_quarto()
and I don't particularly like it in this context as the function is very greedy (returns TRUE if either "_quarto.yml at its root" or "at least one .qmd file in the directory").
I'm thinking about using something like knitr::current_input()
to see if the file extension is .qmd
, but this would require some testing and may not behave well with secondary applications such as pkgdown
. I'll keep you posted.
That looks good. Is it the case that options("quartoEqn")
is NULL
by default, and presently must be set TRUE
to use in a quarto doc?
Currently, yes, one would need to use options("quartoEqn" = TRUE)
at the beginning of the document to switch to Quarto mode.
I have a working solution to this problem in https://github.com/friendly/matlib/blob/master/dev/Eqn_test_quarto.qmd but it involves a file name constraint in that, for example, mydoc.qmd
and mydoc.Rmd
or mydoc.Rnw
cannot live in the same directory, otherwise an error will be raised. If we're fine with this file naming constraint I'd be happy to port this automation as it should work with 'pkgdown' too.
Is setQuartoEqn()
to be called by the user, or will this be called by Eqn()
and friends?
The latter; this shouldn't be the user's problem to automate.
Updates to this thread: quarto support now fully functional up to the unique .qmd
file limitation, and preview.pdf
and preview.packages
options have been added to generate equations using LaTeX compliers rather than MathJax whenever this is useful.
and with a complied document
(not that it's helpful with the border matrix feature, just showing this is possible to preview when PDFs are built).
Also, printEqn()
now detects Greek letters so that **
will apply a \boldsymbol{}
to detected Greek letters rather than the less attractive \mathbf{}
.
Does it make sense to support \bordermatrix
optionally in print.latexMatrix()
, say via an argument bordermatrix
, which gets its default value from an option and defaults to FALSE
if the option isn't set?
Yes, I think that's reasonable. It's unfortunate that a side-step is required to deal with MathJax limitations, though having the option to use the more kosher version for PDF outputs is attractive and IMO preferable.
OK, I'll do that when I have a chance.
I added support for \bordermatrix{}
in print.latexMatrix()
. The implementation is straightforward and seems to work fine (but, as usual, should be tested more). A limitation of \bordermatrix{}
is that it apparently doesn't support matrix delimiters other than parentheses.
I've placed a barebones parser in
dev/eqn_parser.R
which implements some of the ideas I was thinking w.r.t. reducing the amount of LaTeX code for the novice user, but still allow power users freedom. The idea is to try and reduce equations such asto something analogous to markdown but for LaTeX equations, such as
Of course, the main limitation is that LaTeX has many more environments to choose from, so I've left it possible for users to define what
*
and**
should mean in this context, among others. This parser also allows for macro definitions, where for example'*'
will give\\times
and%n
will give the same string that's currently provided byEqn_newline()
. Other macros starting with%
are easy to add at this point.There are number of other avenues to go, such as detecting Greek letter inputs to, say, replace
beta -> \\beta
to reduce the\\
requirements, but I worry about going too deep here.