assemble_rtf() concatenates several RTF files generated by
generate_rtfreport() into a single deliverable. Each input file
becomes one or more sections of the assembled output; the document
header (font / colour tables, page settings) is taken from the
first input.
Arguments
- input_files
Character vector of paths to RTF files to combine (at least 2). May be left out when
tocis a table (or its path): the table'sfilecolumn, in its order.- output_file
Path for the assembled output RTF file.
- overwrite
Logical; whether to overwrite an existing output file. Default
FALSE.- cover
Optional
list(title, subtitle, date, version, meta)for a cover page.NULL(default) = no cover page.- toc
Table-of-Contents specification.
NULL(default) = no TOC, no bookmarks;"auto"= auto-extract titles; a character vector = one label per input file; a table (columnsfile,label,heading,level) or the path of one (.xlsx/.csv) = multi-level layout. See Table of Contents above.- toc_title
Centred bold title rendered on the TOC page. Default
"Table of Contents".- toc_leader
"dot"(default) draws a dotted leader between each TOC entry and its page number;"none"leaves whitespace.- toc_page_numbering
"none"(default) /"roman"/"decimal". See Page numbering above.- bookmark_prefix
String prepended to every auto-generated bookmark name (default
"tfl_"). Helps avoid clashes if you later concatenate multiple assembled outputs.- book_page
Text for the compiled document's page number, put into every
{BOOK_PAGE}slot the inputs reserved.NULL(default) leaves the slots empty.A deliverable that will be bound into a book needs two page numbers: its own (
Page 1 of 3) and the book's (Page 4 of 57). Written from the start they print the same number twice on a standalone deliverable, where the two are equal. So the deliverable reserves the position instead –c(c = "{BOOK_PAGE}")in whichever band it wants, header, footer, title or footnote – and renders it empty, keeping the row's height. This argument supplies the content when the book is built, so filling it cannot shift anything.Typically
"Page {AUTO_PAGE} of {AUTO_TOTAL_PAGES}". The total resolves to the book's page count, which is what the deliverable could not know on its own. The static{PAGE}/{TOTAL_PAGES}are rejected: the slot sits in one band shared by every page of a section, so a single substitution cannot give each page its own number.
Details
Page-number fields work correctly across the assembled document provided the header/footer text uses dynamic tokens:
{AUTO_PAGE}– per-page number rendered by the RTF viewer.{AUTO_TOTAL_PAGES}– total page count rendered by the viewer across all assembled files.
Static tokens ({TOTAL_PAGES}) reflect only the page count
of the individual source file and will be wrong in the assembled
output.
Cover page
Pass cover = list(...) to add a cover page section before the TOC.
Recognised fields:
titlelarge centred bold heading (default font size 22 pt).
subtitlemedium centred line below the title (14 pt).
datecentred line (11 pt).
versioncentred line (11 pt).
metacharacter vector of extra centred lines (10 pt).
Any field that is NULL or empty is skipped.
Table of Contents
toc can take any of these shapes:
NULL(default)no TOC, no bookmarks. Byte-for-byte the pre-v0.0.29 behaviour.
"auto"auto-extract each input file's title (the first centred-bold cell of the title block) and use it as a level-1 TOC entry. Falls back to the file's basename if no title is detected.
- a character vector of TOC labels
one per input file – same as
"auto"but with explicit labels.- a table (
data.frame) one row per file, in order, for multi-level (chapter / table) layouts:
file(the path),label(the entry text), and optionallyheading(a heading printed above the row's entry whenever it changes;NA= none),level(the entry's indent, default 2) andorder.assemble_folder()makes one from a folder, ready to edit.input_filescan then be left out: the table'sfilecolumn is used.- the path of such a table
an
.xlsxor.csvfile, e.g. the oneassemble_folder(spec_file = )wrote and you edited.- a
list(...)oftoc_heading()andtoc_entry()objects the older spelling of the table (deprecated).
Each TOC entry is an RTF HYPERLINK field; clicking it in
Word / Pages jumps to a per-source-file bookmark. Each row also
has a PAGEREF field so the page number next to the entry is
calculated by the viewer when the file opens.
Page numbering
toc_page_numbering controls how the TOC pages (and cover, if
present) are numbered:
"none"(default)Arabic numbering flows continuously from the first page; if the source files use
{AUTO_PAGE}the TOC counts as page 1, 2, ..."roman"TOC pages use lowercase Roman numerals (
i,ii, ...); body pages restart at1."decimal"TOC pages use Arabic numerals starting at
1; body pages restart at1.
Examples
# two TFL files in a folder, as a study's output
dir <- file.path(tempdir(), "tfl")
dir.create(dir, showWarnings = FALSE)
for (t in c("14.1.1", "14.2.1")) {
doc <- rtf_document() |>
rtf_tables(data.frame(Parameter = "Age", Value = "75.1")) |>
rtf_titles(list(c(paste("Table", t), "Safety Population")))
generate_rtfreport(doc, file.path(dir, paste0("t", gsub(".", "_", t,
fixed = TRUE), ".rtf")), overwrite = TRUE)
}
a <- file.path(dir, "t14_1_1.rtf")
b <- file.path(dir, "t14_2_1.rtf")
out <- tempfile(fileext = ".rtf")
# Plain concatenation (legacy behaviour)
assemble_rtf(c(a, b), out, overwrite = TRUE)
# Auto-TOC: one entry per file, label extracted from each title
assemble_rtf(c(a, b), out, toc = "auto", overwrite = TRUE)
# Multi-level TOC with section headings + cover page + Roman TOC pages
assemble_rtf(
input_files = c(a, b),
output_file = out,
cover = list(
title = "Study XYZ-001",
subtitle = "Final Statistical Report",
date = "2026-05-28",
version = "v1.0",
meta = c("Confidential", "Prepared by ACME Pharma")
),
toc = data.frame(
file = c(a, b),
heading = c("DEMOGRAPHICS", "SAFETY ANALYSES"),
label = c("Table 14.1.1 Demographics", "Table 14.2.1 Adverse Events")
),
toc_page_numbering = "roman",
overwrite = TRUE
)