Skip to contents

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.

Usage

assemble_rtf(
  input_files = NULL,
  output_file,
  overwrite = FALSE,
  cover = NULL,
  toc = NULL,
  toc_title = "Table of Contents",
  toc_leader = c("dot", "none"),
  toc_page_numbering = c("none", "roman", "decimal"),
  bookmark_prefix = "tfl_",
  book_page = NULL
)

Arguments

input_files

Character vector of paths to RTF files to combine (at least 2). May be left out when toc is a table (or its path): the table's file column, 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 (columns file, 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.

Value

Invisibly returns output_file.

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:

title

large centred bold heading (default font size 22 pt).

subtitle

medium centred line below the title (14 pt).

date

centred line (11 pt).

version

centred line (11 pt).

meta

character 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 optionally heading (a heading printed above the row's entry whenever it changes; NA = none), level (the entry's indent, default 2) and order. assemble_folder() makes one from a folder, ready to edit. input_files can then be left out: the table's file column is used.

the path of such a table

an .xlsx or .csv file, e.g. the one assemble_folder(spec_file = ) wrote and you edited.

a list(...) of toc_heading() and toc_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 at 1.

"decimal"

TOC pages use Arabic numerals starting at 1; body pages restart at 1.

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
)