Open hughjonesd opened 7 months ago
Before I dig in deeper:
---
title: "Quarto tester"
format: html
---
The following document will fail if compiled to PDF
Can you clarify and fix your example?
It'll be hard to make this work in Quarto's new crossref system. Huxtable is emitting its own opinionated crossref entries and those are interfering with Quarto's. The raw LaTeX being emitted here is:
```{=latex}
\providecommand{\huxb}[2]{\arrayrulecolor[RGB]{#1}\global\arrayrulewidth=#2pt}
\providecommand{\huxvb}[2]{\color[RGB]{#1}\vrule width #2pt}
\providecommand{\huxtpad}[1]{\rule{0pt}{#1}}
\providecommand{\huxbpad}[1]{\rule[-#1]{0pt}{#1}}
\begin{table}[ht]
\begin{centerbox}
\begin{threeparttable}
\label{tab:tbl-hux}
\setlength{\tabcolsep}{0pt}
\begin{tabular}{l l}
\hhline{}
\arrayrulecolor{black}
\multicolumn{1}{!{\huxvb{0, 0, 0}{0}}l!{\huxvb{0, 0, 0}{0}}}{\huxtpad{6pt + 1em}\raggedright \hspace{6pt} Type \hspace{6pt}\huxbpad{6pt}} &
\multicolumn{1}{r!{\huxvb{0, 0, 0}{0}}}{\huxtpad{6pt + 1em}\raggedleft \hspace{6pt} Price \hspace{6pt}\huxbpad{6pt}} \tabularnewline[-0.5pt]
\hhline{}
\arrayrulecolor{black}
\multicolumn{1}{!{\huxvb{0, 0, 0}{0}}l!{\huxvb{0, 0, 0}{0}}}{\huxtpad{6pt + 1em}\raggedright \hspace{6pt} Strawberry \hspace{6pt}\huxbpad{6pt}} &
\multicolumn{1}{r!{\huxvb{0, 0, 0}{0}}}{\huxtpad{6pt + 1em}\raggedleft \hspace{6pt} 1.90 \hspace{6pt}\huxbpad{6pt}} \tabularnewline[-0.5pt]
\hhline{}
\arrayrulecolor{black}
\multicolumn{1}{!{\huxvb{0, 0, 0}{0}}l!{\huxvb{0, 0, 0}{0}}}{\huxtpad{6pt + 1em}\raggedright \hspace{6pt} Raspberry \hspace{6pt}\huxbpad{6pt}} &
\multicolumn{1}{r!{\huxvb{0, 0, 0}{0}}}{\huxtpad{6pt + 1em}\raggedleft \hspace{6pt} 2.10 \hspace{6pt}\huxbpad{6pt}} \tabularnewline[-0.5pt]
\hhline{}
\arrayrulecolor{black}
\multicolumn{1}{!{\huxvb{0, 0, 0}{0}}l!{\huxvb{0, 0, 0}{0}}}{\huxtpad{6pt + 1em}\raggedright \hspace{6pt} Plum \hspace{6pt}\huxbpad{6pt}} &
\multicolumn{1}{r!{\huxvb{0, 0, 0}{0}}}{\huxtpad{6pt + 1em}\raggedleft \hspace{6pt} 1.80 \hspace{6pt}\huxbpad{6pt}} \tabularnewline[-0.5pt]
\hhline{}
\arrayrulecolor{black}
\end{tabular}
\end{threeparttable}\par\end{centerbox}
\end{table}
We try to detect and correct `\begin{table}` usage because this means that these tables don't play nicely with our crossreferencing system, but this is a best-effort approach that can't work in all cases. Here, we're getting confused by the \providecommand preamble. (and, in general, we can't detect and handle arbitrary LaTeX in raw code, because parsing LaTeX is impossible).
As a direct example of why we can't support this, the emitted output will never be usable in a Quarto [Supplemental Table](https://quarto.org/docs/authoring/cross-references-custom.html#example-supplemental-figures), because we need to use a different counter than that of the `table` environment. There are other issues too: note eg the label `tab:tbl-hux` emitted by huxtable is incorrect.
The fundamental problem here is that huxtable is trying to decide how its table should be crossreferenced, and that's not working with Quarto's expectations of the LaTeX code.
If you can convince huxtable to produce its own captions directly in the code, then you could use that, and remove the `tbl-cap` entry from your code cell. Then, you could use raw latex references to `tab:tbl-hux` by typing `\ref{tab:tbl-hux}` in your Markdown code (that should pass through to LaTeX directly).
The text reference @tbl-hux
comes out correctly with 1.3.450. What's changed? Huxtable adds "tab:" before knitr labels; It looks like quarto used to rewrite it and remove the "tab:" part. Adding "tab:" was to work with bookdown, IIRC; see https://bookdown.org/yihui/bookdown/tables.html.
In any case, what's breaking TeX compilation is that quarto is removing the \providecommand
commands, even though the .md file produced has a block marked as raw LaTeX:
```{=latex}
\providecommand{\huxb}[2]{\arrayrulecolor[RGB]{#1}\global\arrayrulewidth=#2pt}
\providecommand{\huxvb}[2]{\color[RGB]{#1}\vrule width #2pt}
\providecommand{\huxtpad}[1]{\rule{0pt}{#1}}
\providecommand{\huxbpad}[1]{\rule[-#1]{0pt}{#1}}
...
Is there a way I can mark huxtable output as "please leave as is"? If so then I'm happy to make it follow the rules for cross-referencing, if you can explain what these are.
As a process note, I first discovered this when I got a message from CRAN that huxtable was throwing test errors when used with the new quarto. More notice would have been helpful. I've now got 2 weeks to fix this before the package is archived.
What's changed?
All the 1.4 crossref features.
In any case, what's breaking TeX compilation is that quarto is removing the \providecommand commands, even though the .md file produced has a block marked as raw LaTeX:
As I explained in my comment, if we don't attempt to parse that content, things will break in a different way.
Is there a way I can mark huxtable output as "please leave as is"?
Again, as I explained in my comment:
If you can convince huxtable to produce its own captions directly in the code, then you could use that, and remove the tbl-cap entry from your code cell. Then, you could use raw latex references to tab:tbl-hux by typing \ref{tab:tbl-hux} in your Markdown code (that should pass through to LaTeX directly).
More notice would have been helpful. I've now got 2 weeks to fix this before the package is archived.
I'm sorry you're getting hit by this, by that's CRAN policy that we are not involved with and don't control.
@hughjonesd See https://quarto.org/docs/prerelease/1.4/ to get a view of "what's changed".
As a process note, I first discovered this when I got a message from CRAN that huxtable was throwing test errors when used with the new quarto. More notice would have been helpful. I've now got 2 weeks to fix this before the package is archived.
May I suggest to use CI to test on Quarto pre-release. You are already using CI (with outdated GitHub Actions). CI is useful precisely for these cases. Note that your R CMD Checks on GitHub Actions has been failing for more than a year (https://github.com/hughjonesd/huxtable/actions).
OK, but I'd like people to be able to use the quarto chunk labels, as they can do for bookdown/rmarkdown and could before. It's nicer for the user. Is there a way I can do that? For example, what if I just print the tex label as tbl-hux without the tab: prefix?
More generally, is there a way I can avoid quarto removing the \providecommand
? What conditions trigger that? I need some rules to follow, otherwise I am flying blind. If you don't want people to write arbitrary TeX and/or HTML tables via code, OK, but then I think clarify that.
More generally, is there a way I can avoid quarto removing the \providecommand?
Sorry, but that's what I've tried to answer to you twice. If the LaTeX output is not in a cell that Quarto considers part of its native crossref, then you'll have to manage those yourself, and the raw LaTeX should go through unchanged.
If your question is "can I use Quarto syntax and still use huxtable's complex LaTeX code", then the answer is currently no, unless you figure out a way for huxtable to emit LaTeX code that does table formatting without also doing table crossreferencing.
Right. I'm probably being extremely slow, but could you explain how quarto decides whether a LaTeX table is part of its native crossref? Is it if it emits a \label command? Or is it just anything in a cell with a label: attribute?
You need to emit only the table without \label{tab:tbl-hux}
which is handled by Quarto.
The label is taken from #| label: tbl-mytable
in the code cell.
but could you explain how quarto decides whether a LaTeX table is part of its native crossref? Is it if it emits a \label command?
Our documentation is here: https://quarto.org/docs/authoring/cross-references.html#computations
But, in your case, a code cell with label: tbl-...
and tbl-cap: ...
will be interpreted by Quarto as a table. There are a numbe of other things that we try to detect for backwards compatibility, and that includes pure LaTeX code with \label{}
and \begin{table}
. That's ultimately the reason that you're seeing this failure right now; Quarto is trying to take the LaTeX from huxtable and failing to process it appropriately.
Okay. I did some more testing. Here just for reference is how it works as of 1.4.549:
tbl-
fail to compile, whether set by quarto or huxtable.tbl-
, but they cannot be referred to by quarto-style @...
referencing. \ref{label}
), so long as a caption is also set and the label doesn't start with tbl-
. Quarto labels don't seem to get picked up.I'll write code to emit informative errors/warnings.
An update for 1.5: the following table gets its label eaten, whether or not the label starts with tbl-
.
---
title: "quarto minimal table"
format:
pdf:
keep-tex: true
---
Table \ref{foo}.
```{=tex}
\begin{table}[h]
\caption{A table\label{foo}}
\begin{tabular}{l l}
1 & 2
\end{tabular}
\end{table}
Table \ref{foo}.
Part of the resulting output:
Table \ref{foo}.
\begin{table}[h] \caption{A table} \begin{tabular}{l l} 1 & 2 \end{tabular} \end{table}
Table \ref{foo}.
Quarto emits a warning.
Quarto version: 1.5.45
Bug description
Quarto 1.4 causes huxtable tables to fail when compiling to PDF, because it doesn't print out some LaTeX \providecommand commands that huxtable uses. This is new in 1.4.
Steps to reproduce
The following document will fail if compiled to PDF on quarto 1.4.549 or 1.5.6. It works with quarto 1.3.450.
Quarto 1.5.6 [✓] Checking versions of quarto binary dependencies... Pandoc version 3.1.11: OK Dart Sass version 1.69.5: OK Deno version 1.37.2: OK [✓] Checking versions of quarto dependencies......OK [✓] Checking Quarto installation......OK Version: 1.5.6 Path: /Applications/quarto/bin
[✓] Checking tools....................OK TinyTeX: (external install) Chromium: (not installed)
[✓] Checking LaTeX....................OK Using: TinyTex Path: /Users/davidhugh-jones/Library/TinyTeX/bin/universal-darwin Version: 2023
[✓] Checking basic markdown render....OK
[✓] Checking Python 3 installation....OK Version: 3.11.5 Path: /Library/Frameworks/Python.framework/Versions/3.11/bin/python3 Jupyter: (None)
[✓] Checking R installation...........OK Version: 4.3.2 Path: /Library/Frameworks/R.framework/Resources LibPaths:
[✓] Checking Knitr engine render......OK