Home > Enterprise >  Repeat gt column labels on each page
Repeat gt column labels on each page

Time:09-19

I am using second page, no column header

I can edit the TeX document, adding \endhead after the column header, and I get the result I want on the second (and subsequent) pages.

   158 \begin{longtable}{rr}
   159 \toprule
   160 id & random \\
   161 \midrule
   162 \endhead           

Like this:

second page, with column header

One option to add the \endhead would be to use a Pandoc filter to add the extra longtable command, but that sounds like a lot of effort for something so basic.

Is there a simple way with this workflow (Quarto options, pandoc, gt) to get column headers on each page in the PDF output?

CodePudding user response:

Your question is a topical issue.

So, I can suggest a next one solution.


As you know - we can represent our gt table as a LaTeX code: enter image description here

Considering the place for the header - updating our code (adding \\toprule\nid & random \\\\ \n\\midrule between 42 and 43:

New code:

---
format:
  pdf:
    documentclass: article
    keep-tex: true
include-in-header:
- \usepackage{amsmath, booktabs, caption, longtable}
---


```{r, results='asis', echo=F}

k <- "\\captionsetup[table]{labelformat=empty,skip=1pt}\n\\begin{longtable}{rr}\n\\toprule\nid & random \\\\ \n\\midrule\n1 & 0.83452294 \\\\ \n2 & 0.43130524 \\\\ \n3 & 0.38702311 \\\\ \n4 & 0.75589167 \\\\ \n5 & 0.34432672 \\\\ \n6 & 0.75283676 \\\\ \n7 & 0.72770533 \\\\ \n8 & 0.20232485 \\\\ \n9 & 0.07900835 \\\\ \n10 & 0.80229610 \\\\ \n11 & 0.03800323 \\\\ \n12 & 0.03144921 \\\\ \n13 & 0.87364981 \\\\ \n14 & 0.47587592 \\\\ \n15 & 0.56736249 \\\\ \n16 & 0.83990532 \\\\ \n17 & 0.64138659 \\\\ \n18 & 0.76073451 \\\\ \n19 & 0.66013426 \\\\ \n20 & 0.54178832 \\\\ \n21 & 0.70443849 \\\\ \n22 & 0.81238956 \\\\ \n23 & 0.11305811 \\\\ \n24 & 0.12530444 \\\\ \n25 & 0.22497031 \\\\ \n26 & 0.35093560 \\\\ \n27 & 0.91268645 \\\\ \n28 & 0.19127469 \\\\ \n29 & 0.21638115 \\\\ \n30 & 0.24333619 \\\\ \n31 & 0.21178737 \\\\ \n32 & 0.50896038 \\\\ \n33 & 0.30918302 \\\\ \n34 & 0.44719810 \\\\ \n35 & 0.20445296 \\\\ \n36 & 0.67448123 \\\\ \n37 & 0.78824962 \\\\ \n38 & 0.62888684 \\\\ \n39 & 0.39583956 \\\\ \n40 & 0.99218439 \\\\ \n41 & 0.27330819 \\\\ \n42 & 0.20861772 \\\\ \\toprule\nid & random \\\\ \n\\midrule \n43 & 0.67226113 \\\\ \n44 & 0.11676375 \\\\ \n45 & 0.24479000 \\\\ \n46 & 0.28968861 \\\\ \n47 & 0.72271636 \\\\ \n48 & 0.58395987 \\\\ \n49 & 0.74914347 \\\\ \n50 & 0.32712809 \\\\ \n\\bottomrule\n\\end{longtable}\n"

knitr::asis_output(k)

```

The desired output:

enter image description here


So, the main idea of this method: first render of qmd-file -> detect the break -> manually add the header.

CodePudding user response:

Since we only need to add the \endhead after the \midrule, one option could be inserting \endhead after the \midrule (Using the answer from @manro),


---
title: "Random Table"
format:
  pdf:
    keep-tex: true
---

```{r}
#| echo: false
#| warning: false
#| results: asis

library(tidyverse)
library(gt)

random <- tibble(
  id = seq(1:50),
  random = runif(50)
)

t <- gt(random) %>%
  as_latex() %>%
  as.character()

knitr::asis_output(gsub("(.*\\\\begin\\{longtable\\}.*?\\midrule\\\n)", t, replacement = "\\1\\\\endhead\\\n"))
```


enter image description here


CodePudding user response:

I found a way to solve this problem for my documents using pandoc filters. I'm still hoping there is a more elegant solution or that this is a feature that could be added to gt, but here's what I did.

Add the filter to the pdf section of the YAML header:

format:
  pdf:
    filters:
      - endhead.lua

And here's the endhead.lua filter:

function RawBlock(elem)
    -- print(elem.text)
    return {
        pandoc.RawInline(
            "latex",
            string.gsub(
              elem.text, 
              "\\toprule\n(.-)\\midrule\n",
              "\\toprule\n%1\\midrule\n\\endhead\n"
            )
        ),
    }
end

gt within an R code block produces a RawBlock element in Pandoc's AST, so that's what needs to be changed using the filter. You can figure out the element you need to manipulate by adding keep-md: true to the YAML header of your Quarto doc, then after rendering, do:

$ pandoc -s -t native tables.md

That will show you the AST.

Once you know the Pandoc element, it's just a question of figuring out the regular expression that will add an \endhead element to the proper section of the table. I did this by finding the first \midrule after \toprule in each RawBlock (gt table). It took a bit for me to figure out how to use non-greedy capturing ((.-)) in order to only add \endhead once, right after the header of the table.

  • Related