From cd94c581bc5d35a37ccabe2f5e7e7427a164b359 Mon Sep 17 00:00:00 2001 From: Carlos Scheidegger Date: Thu, 16 Nov 2023 13:32:48 -0700 Subject: [PATCH] handle longtable in new crossref system --- .../filters/customnodes/floatreftarget.lua | 33 +++++++++++++++++++ src/resources/filters/main.lua | 7 ++-- src/resources/filters/quarto-post/latex.lua | 22 ++++++++++++- .../filters/quarto-pre/table-captions.lua | 15 --------- tests/docs/smoke-all/2023/11/16/7604.qmd | 29 ++++++++++++++++ 5 files changed, 85 insertions(+), 21 deletions(-) create mode 100644 tests/docs/smoke-all/2023/11/16/7604.qmd diff --git a/src/resources/filters/customnodes/floatreftarget.lua b/src/resources/filters/customnodes/floatreftarget.lua index a48234efd67..ceb6d1ed3fd 100644 --- a/src/resources/filters/customnodes/floatreftarget.lua +++ b/src/resources/filters/customnodes/floatreftarget.lua @@ -272,6 +272,39 @@ end, function(float) arg = pandoc.Span(quarto.utils.as_inlines(latex_caption or {}) or {}) -- unnecessary to do the "or {}" bit but the Lua analyzer doesn't know that }) + -- special case for singleton longtable floats + if float_type == "tbl" then + local raw + _quarto.ast.walk(float.content, { + RawBlock = function(el) + if _quarto.format.isRawLatex(el) and el.text:match(_quarto.patterns.latexLongtablePattern) then + raw = el + end + end + }) + if raw then + local longtable_content = raw.text:gsub(_quarto.patterns.latexLongtablePattern, "%2", 1) + -- split the content into params and actual content + -- params are everything in the first line of longtable_content + -- actual content is everything else + local params, content = longtable_content:match("^(.-)\n(.*)$") + local result = pandoc.Blocks({latex_caption, pandoc.RawInline("latex", "\\\\")}) + local cap_loc = cap_location(float) + -- if cap_loc is top, insert content on bottom + if cap_loc == "top" then + result:insert(pandoc.RawBlock("latex", content)) + else + result:insert(1, pandoc.RawBlock("latex", content)) + end + + result:insert(1, pandoc.RawBlock("latex", "\\begin{longtable}" .. params)) + result:insert(pandoc.RawBlock("latex", "\\end{longtable}")) + return result + end + end + + + if float.parent_id then -- need to fixup subtables because nested longtables appear to give latex fits local vAlign = validatedVAlign(float.attributes[kLayoutVAlign]) diff --git a/src/resources/filters/main.lua b/src/resources/filters/main.lua index b75890d1097..b8dad595d95 100644 --- a/src/resources/filters/main.lua +++ b/src/resources/filters/main.lua @@ -253,11 +253,7 @@ local quarto_pre_filters = { { name = "pre-table-captions", filter = table_captions(), flags = { "has_table_captions" } }, - - { name = "pre-longtable-no-caption-fixup", - filter = longtable_no_caption_fixup(), - flags = { "has_longtable_no_caption_fixup" } }, - + { name = "pre-code-annotations", filter = code_annotations(), flags = { "has_code_annotations" } }, @@ -346,6 +342,7 @@ local quarto_post_filters = { { name = "layout-meta-inject-latex-packages", filter = layout_meta_inject_latex_packages() }, -- format fixups post rendering + { name = "post-render-latex-fixups", filter = render_latex_fixups() }, { name = "post-render-html-fixups", filter = render_html_fixups() }, { name = "post-render-ipynb-fixups", filter = render_ipynb_fixups() }, { name = "post-render-typst-fixups", filter = render_typst_fixups() }, diff --git a/src/resources/filters/quarto-post/latex.lua b/src/resources/filters/quarto-post/latex.lua index 2879b778406..608b4281edf 100644 --- a/src/resources/filters/quarto-post/latex.lua +++ b/src/resources/filters/quarto-post/latex.lua @@ -378,4 +378,24 @@ function render_latex() return pandoc.Div(calloutContents) end } -end \ No newline at end of file +end + + +function render_latex_fixups() + if not _quarto.format.isLatexOutput() then + return {} + end + + return { + RawBlock = function(raw) + if _quarto.format.isRawLatex(raw) then + if (raw.text:match(_quarto.patterns.latexLongtablePattern) and + not raw.text:match(_quarto.patterns.latexCaptionPattern)) then + raw.text = raw.text:gsub( + _quarto.patterns.latexLongtablePattern, "\\begin{longtable*}%2\\end{longtable*}", 1) + return raw + end + end + end + } +end diff --git a/src/resources/filters/quarto-pre/table-captions.lua b/src/resources/filters/quarto-pre/table-captions.lua index 4a76b2c7250..d12460805b0 100644 --- a/src/resources/filters/quarto-pre/table-captions.lua +++ b/src/resources/filters/quarto-pre/table-captions.lua @@ -6,21 +6,6 @@ local patterns = require("modules/patterns") kTblCap = "tbl-cap" kTblSubCap = "tbl-subcap" -function longtable_no_caption_fixup() - return { - RawBlock = function(raw) - if _quarto.format.isRawLatex(raw) then - if (raw.text:match(_quarto.patterns.latexLongtablePattern) and - not raw.text:match(_quarto.patterns.latexCaptionPattern)) then - raw.text = raw.text:gsub( - _quarto.patterns.latexLongtablePattern, "\\begin{longtable*}%2\\end{longtable*}", 1) - return raw - end - end - end - } -end - function table_captions() return { Div = function(el) diff --git a/tests/docs/smoke-all/2023/11/16/7604.qmd b/tests/docs/smoke-all/2023/11/16/7604.qmd new file mode 100644 index 00000000000..9577b89cc21 --- /dev/null +++ b/tests/docs/smoke-all/2023/11/16/7604.qmd @@ -0,0 +1,29 @@ +--- +title: "7604" +format: pdf +--- + +```{r} +library(kableExtra) +``` + +```{r} +#| label: tbl-sad-broken +#| tbl-cap: "This table is cross-referenceable but no longer breaks across pages because it's inside `\\centering{}`" +rbind(mtcars, mtcars) |> + kbl(longtable = TRUE, booktabs = TRUE) |> + kable_styling() +``` + +::: {#tbl-also-sad} +```{r} +rbind(mtcars, mtcars) |> + kbl(longtable = TRUE, booktabs = TRUE) |> + kable_styling() +``` + +This table is also cross-referenceable but also doesn't break across pages because of the same `\centering{}` problem +::: + + +see @tbl-sad-broken and @tbl-also-sad.