The Problem
If a user specifies a cols_width() value using the pct() function and tries to render to PDF, the render will fail with an error at the LaTeX compile stage (exact line number of the error depends on document content):
compilation failed- error
Paragraph ended before \scr@LT@array was complete.
<to be read again>
\par
l.195
Expected Behavior
Using a pct() call to specify column widths with cols_width() when outputting to LaTeX/PDF should not produce an error.
Actual Behavior
The resulting knitted document produces an error at the LaTeX compilation stage.
Minimal Reproducible R Script
Compiling this script as its own file should produce the LaTeX error.
Also, by preserving LaTeX output we can visually inspect the generated LaTeX.
#' ---
#' output:
#' pdf_document:
#' keep_md: true
#' keep_tex: true
#'
#' ---
library(gt)
library(sessioninfo)
mtcars |> gt() |>
cols_width(everything() ~ pct(15)) # an arbitrary column width for example purposes
session_info()
The Offending LaTeX Lines
\begin{longtable}{>{\raggedleft\arraybackslash}p{15%}>{\raggedleft\arraybackslash}p{15%}>{\raggedleft\arraybackslash}p{15%}>{\raggedleft\arraybackslash}p{15%}>{\raggedleft\arraybackslash}p{15%}>{\raggedleft\arraybackslash}p{15%}>{\raggedleft\arraybackslash}p{15%}>{\raggedleft\arraybackslash}p{15%}>{\raggedleft\arraybackslash}p{15%}>{\raggedleft\arraybackslash}p{15%}>{\raggedleft\arraybackslash}p{15%}}
We can see from the LaTeX above that the % is causing all characters following it to be treated as a comment, rather than executable LaTeX.
Tracing the Problem through gt
- When a user specifies a percentage with
pct() inside a cols_width() call, the pct() call just takes that number and converts it into a string by concatenating a raw % to the number.
- That string value---which includes the raw
% sign, gets passed to create_table_start_l(). On line 175 of that function, if the value of col_widths[i] isn't null, we eventually move to line 186, where col_widths[i] gets pasted in seemingly without any check as to whether it contains a raw % sign.
- At this point
col_widths[i] will necessarily contain the raw percent sign. So...
- The resulting text:
"p{", col_widths[i], "}" gets passed on to LaTeX, where the LaTeX compiler interprets anything following an unescaped % as a comment.
- The call to
p{} in LaTeX never gets a closing brace, because of the comment symbol.
- LaTeX fails to compile the document.
A Temporary Work-Around
Instead of calling pct(), a user can specify a string literal with a backslash-escaped %, as in this fully reproducible script
#' ---
#' output:
#' pdf_document:
#' keep_md: true
#' keep_tex: true
#'
#' ---
library(gt)
mtcars |> gt() |>
cols_width(everything() ~ "15\\%")
Session Info
─ Session info ────────────────────────────────────────────────────────────────────────
setting value
version R version 4.3.1 (2023-06-16)
os macOS Ventura 13.5.2
system aarch64, darwin20
ui RStudio
language (EN)
collate en_US.UTF-8
ctype en_US.UTF-8
tz America/New_York
date 2023-10-06
rstudio 2023.06.1+524 Mountain Hydrangea (desktop)
pandoc 3.1.7 @ /opt/homebrew/bin/ (via rmarkdown)
─ Packages ────────────────────────────────────────────────────────────────────────────
package * version date (UTC) lib source
bit 4.0.5 2022-11-15 [1] CRAN (R 4.3.0)
bit64 4.0.5 2020-08-30 [1] CRAN (R 4.3.0)
cli 3.6.1 2023-03-23 [1] CRAN (R 4.3.0)
crayon 1.5.2 2022-09-29 [1] CRAN (R 4.3.0)
digest 0.6.33 2023-07-07 [1] CRAN (R 4.3.0)
dplyr * 1.1.3 2023-09-03 [1] CRAN (R 4.3.0)
evaluate 0.22 2023-09-29 [1] CRAN (R 4.3.1)
fansi 1.0.4 2023-01-22 [1] CRAN (R 4.3.0)
fastmap 1.1.1 2023-02-24 [1] CRAN (R 4.3.0)
generics 0.1.3 2022-07-05 [1] CRAN (R 4.3.0)
glue 1.6.2 2022-02-24 [1] CRAN (R 4.3.0)
gt * 0.9.0.9000 2023-10-06 [1] Github (wildoane/gt@aee1944)
here * 1.0.1 2020-12-13 [1] CRAN (R 4.3.0)
hms 1.1.3 2023-03-21 [1] CRAN (R 4.3.0)
htmltools 0.5.6 2023-08-10 [1] CRAN (R 4.3.0)
janitor * 2.2.0 2023-02-02 [1] CRAN (R 4.3.0)
knitr 1.44 2023-09-11 [1] CRAN (R 4.3.0)
lifecycle 1.0.3 2022-10-07 [1] CRAN (R 4.3.0)
lubridate 1.9.3 2023-09-27 [1] CRAN (R 4.3.1)
magrittr * 2.0.3 2022-03-30 [1] CRAN (R 4.3.0)
pillar 1.9.0 2023-03-22 [1] CRAN (R 4.3.0)
pkgconfig 2.0.3 2019-09-22 [1] CRAN (R 4.3.0)
purrr 1.0.2 2023-08-10 [1] CRAN (R 4.3.0)
R6 2.5.1 2021-08-19 [1] CRAN (R 4.3.0)
readr * 2.1.4 2023-02-10 [1] CRAN (R 4.3.0)
rlang 1.1.1 2023-04-28 [1] CRAN (R 4.3.0)
rmarkdown 2.25 2023-09-18 [1] CRAN (R 4.3.1)
rprojroot 2.0.3 2022-04-02 [1] CRAN (R 4.3.0)
rstudioapi 0.15.0 2023-07-07 [1] CRAN (R 4.3.0)
sass 0.4.7 2023-07-15 [1] CRAN (R 4.3.0)
sessioninfo * 1.2.2 2021-12-06 [1] CRAN (R 4.3.0)
snakecase 0.11.1 2023-08-27 [1] CRAN (R 4.3.0)
stringi 1.7.12 2023-01-11 [1] CRAN (R 4.3.0)
stringr * 1.5.0 2022-12-02 [1] CRAN (R 4.3.0)
tibble * 3.2.1 2023-03-20 [1] CRAN (R 4.3.0)
tidyr * 1.3.0 2023-01-24 [1] CRAN (R 4.3.0)
tidyselect 1.2.0 2022-10-10 [1] CRAN (R 4.3.0)
timechange 0.2.0 2023-01-11 [1] CRAN (R 4.3.0)
tzdb 0.4.0 2023-05-12 [1] CRAN (R 4.3.0)
utf8 1.2.3 2023-01-31 [1] CRAN (R 4.3.0)
vctrs 0.6.3 2023-06-14 [1] CRAN (R 4.3.0)
vroom 1.6.3 2023-04-28 [1] CRAN (R 4.3.0)
withr 2.5.1 2023-09-26 [1] CRAN (R 4.3.1)
xfun 0.40 2023-08-09 [1] CRAN (R 4.3.0)
xml2 1.3.5 2023-07-06 [1] CRAN (R 4.3.0)
yaml 2.3.7 2023-01-23 [1] CRAN (R 4.3.0)
[1] /Library/Frameworks/R.framework/Versions/4.3-arm64/Resources/library
───────────────────────────────────────────────────────────────────────────────────────
The Problem
If a user specifies a
cols_width()value using thepct()function and tries to render to PDF, the render will fail with an error at the LaTeX compile stage (exact line number of the error depends on document content):Expected Behavior
Using a
pct()call to specify column widths withcols_width()when outputting to LaTeX/PDF should not produce an error.Actual Behavior
The resulting knitted document produces an error at the LaTeX compilation stage.
Minimal Reproducible R Script
Compiling this script as its own file should produce the LaTeX error.
Also, by preserving LaTeX output we can visually inspect the generated LaTeX.
The Offending LaTeX Lines
We can see from the LaTeX above that the
%is causing all characters following it to be treated as a comment, rather than executable LaTeX.Tracing the Problem through
gtpct()inside acols_width()call, thepct()call just takes that number and converts it into a string by concatenating a raw%to the number.%sign, gets passed tocreate_table_start_l(). On line 175 of that function, if the value ofcol_widths[i]isn't null, we eventually move to line 186, wherecol_widths[i]gets pasted in seemingly without any check as to whether it contains a raw%sign.col_widths[i]will necessarily contain the raw percent sign. So..."p{", col_widths[i], "}"gets passed on to LaTeX, where the LaTeX compiler interprets anything following an unescaped%as a comment.p{}in LaTeX never gets a closing brace, because of the comment symbol.A Temporary Work-Around
Instead of calling
pct(), a user can specify a string literal with a backslash-escaped%, as in this fully reproducible scriptSession Info