skip_on_cran() library(officer) library(xml2) # -- test data --------------------------------------------------------------- dat <- data.frame( label = c("bold", "link", "code", "xref"), content = c( "This is **bold** text", "Visit [Quarto](https://quarto.org)", "Use `print()` here", "See @tbl-results" ), stringsAsFactors = FALSE ) ft_qmd <- flextable(dat) ft_qmd <- mk_par(ft_qmd, j = "content", value = as_paragraph(as_qmd(content))) # -- as_qmd() object creation ------------------------------------------------ test_that("as_qmd creates a chunk with qmd_data", { chunk <- as_qmd("**bold**") expect_true(inherits(chunk, "data.frame")) expect_true("qmd_data" %in% colnames(chunk)) expect_equal(chunk$qmd_data, "**bold**") expect_equal(chunk$txt, "**bold**") }) test_that("as_qmd uses display as fallback text", { chunk <- as_qmd("@tbl-results", display = "Table 1") expect_equal(chunk$txt, "Table 1") expect_equal(chunk$qmd_data, "@tbl-results") }) # -- DOCX markers () ------------------------------------ test_that("DOCX output contains TBLQMD markers", { docx_file <- tempfile(fileext = ".docx") save_as_docx(ft_qmd, path = docx_file) doc <- read_docx(docx_file) body <- docx_body_xml(doc) # structure: header + data rows rows <- xml_find_all(body, "w:body/w:tbl/w:tr") expect_length(rows, nrow(dat) + 1) # label column: regular text labels <- xml_text(xml_find_all( body, "w:body/w:tbl/w:tr[position()>1]/w:tc[1]" )) expect_equal(labels, dat$label) # content column: TBLQMD markers in raw XML doc_str <- as.character(body) markers <- regmatches( doc_str, gregexpr("", doc_str) )[[1]] expect_length(markers, nrow(dat)) # markers should NOT be wrapped in ... expect_false(grepl("", "\\1", markers[i]) expect_equal(officer::from_base64(encoded), dat$content[i]) } }) # -- HTML markers () ---------------------------- test_that("HTML output contains data-qmd-base64 spans", { html_str <- flextable:::gen_raw_html(ft_qmd) # each cell should produce a data-qmd-base64 span spans <- regmatches( html_str, gregexpr('data-qmd-base64="[^"]+"', html_str) )[[1]] expect_length(spans, nrow(dat)) # extract and decode the first marker encoded <- sub('data-qmd-base64="([^"]+)"', "\\1", spans[1]) decoded <- officer::from_base64(encoded) expect_equal(decoded, dat$content[1]) }) # -- LaTeX markers (\tblqmd{base64}) ---------------------------------------- test_that("LaTeX output contains tblqmd markers", { latex_str <- flextable:::knit_to_latex( ft_qmd, bookdown = FALSE, quarto = TRUE ) # each cell should produce a \tblqmd{...} marker markers <- regmatches( latex_str, gregexpr("\\\\tblqmd\\{([A-Za-z0-9+/=]+)\\}", latex_str) )[[1]] expect_length(markers, nrow(dat)) # decode the first marker encoded <- sub("\\\\tblqmd\\{(.+)\\}", "\\1", markers[1]) decoded <- officer::from_base64(encoded) expect_equal(decoded, dat$content[1]) }) # -- use_flextable_qmd() installs the extension ----------------------------- test_that("use_flextable_qmd copies extension files", { tmp_project <- tempfile("qmd_project_") dir.create(tmp_project) path <- use_flextable_qmd(path = tmp_project, quiet = TRUE) ext_dir <- file.path(tmp_project, "_extensions", "flextable-qmd") expect_true(dir.exists(ext_dir)) expect_true(file.exists(file.path(ext_dir, "_extension.yml"))) expect_true(file.exists(file.path(ext_dir, "flextable-qmd.lua"))) expect_true(file.exists(file.path(ext_dir, "unwrap-float.lua"))) unlink(tmp_project, recursive = TRUE, force = TRUE) }) # -- mixed content: as_qmd alongside regular chunks ------------------------- test_that("as_qmd works alongside other chunk types in DOCX", { mixed <- data.frame( a = c("row1", "row2"), b = c("plain text", "also plain"), stringsAsFactors = FALSE ) ft_mix <- flextable(mixed) ft_mix <- mk_par(ft_mix, i = 1, j = "a", value = as_paragraph( as_chunk("prefix: "), as_qmd("**bold ref** to @tbl-x") )) docx_file <- tempfile(fileext = ".docx") save_as_docx(ft_mix, path = docx_file) doc <- read_docx(docx_file) doc_str <- as.character(docx_body_xml(doc)) # regular chunk produces text run expect_true(grepl("prefix: ", doc_str)) # as_qmd chunk produces TBLQMD marker expect_true(grepl("