This guide covers the complete styling system in ksTFL:
Style primitives (s_* helpers) for
fonts, paragraphs, spacing, indentation, tables, and borders
Declaring named styles with
add_style()
Referencing and combining styles with style
references and f_combine()
Applying styles to columns, labels, stubs, and content
Best practices for maintainable, reusable style systems
For runnable reporting examples integrating styles see Reporting Examples. For a quick start see Getting Started.
This is the reference vignette for readers building reusable style systems for teams or studies. The focus is style primitives, composition, references, and maintainable conventions.
Clinical documents live or die on consistency: one font decision,
applied everywhere. ksTFL uses a named style system — declare styles
once with add_style(), reference them by id, compose with
f_combine(), and let create_report()
consolidate the combinations into final render-time styles. One
definition change updates every reference, and complex looks (font +
alignment + background) are assembled from small blocks rather than
hand-written per table.
define_cols(),
add_title(), add_span_header() (with
tidyselect support), use labelStyleRef or
valueStyleRef to point to styles by idf_combine()
to merge multiple styles on-the-fly for ad-hoc combinationscreate_report() consolidate: The
report builder automatically merges combined styles so the renderer
receives clean, consolidated stylesspec$attribs$styles — let the package manage
consolidationStyle primitives begin with s_. s_font(),
s_paragraph() and s_table_style() go directly
inside add_style(); s_spacing(),
s_indents(), s_borders() and
s_border() nest one level deeper (inside
s_paragraph()/s_table_style(), or inside
s_borders()). Calling any of them outside its context
aborts with a clear message. They validate parameter values (colors,
enums, length units) and abort with the allowed set in the message.
Template JSON keys, by contrast, are silently ignored when unknown —
check spelling there yourself.
s_font() — Font propertiesControl font appearance (name, size, weight, color, decorations).
Parameters:
font_name: Font family — one of the seven allowed
names: “Arial”, “Times New Roman”, “Courier New”, “Georgia”, “Verdana”,
“Trebuchet MS”, “Liberation Sans” (see Font Management)font_size: Size with units (e.g., “12pt”, “11pt”)bold: Logical (TRUE/FALSE)italic: Logical (TRUE/FALSE)underline: Logical (TRUE/FALSE)strikethrough: Logical (TRUE/FALSE)color: Color as hex code (e.g., “#000000”, “#FF0000”)
or color name (e.g., “red”, “black”, “blue”)highlight: Background highlight color as hex code or
color nameExample:
spec <- create_table(mtcars)
# Bold, 12pt Arial, red text (using hex code)
spec <- add_style(spec, id = "header_bold_red",
s_font(font_name = "Arial", font_size = "12pt", bold = TRUE, color = "#CC0000"))
# Underlined, 10pt monospace, blue text (using color name)
spec <- add_style(spec, id = "code_style",
s_font(font_name = "Courier New", font_size = "10pt", underline = TRUE, color = "blue"))
# Yellow highlight with black text
spec <- add_style(spec, id = "highlighted",
s_font(color = "black", highlight = "yellow"))s_paragraph() — Paragraph propertiesControl text alignment, spacing before/after, line spacing, and indentation.
Parameters:
alignment: Text alignment — “left”, “right”, “center”,
“justify”, “distributed”spacing: Spacing before/after (use
s_spacing(...))indents: Left/right indentation, first-line indent (use
s_indents(...))word_style: base Word style to inherit from (“Normal”,
“Heading 1”, “Heading 2”, “Title”, “Subtitle”, “No Spacing”, “Strong”,
“Quote”, “Intense Quote”)borders: paragraph-level borders via
s_borders(...) (see Paragraph-level borders below)Example:
spec <- create_table(mtcars)
# Centered text with 6pt spacing before/after
spec <- add_style(spec, id = "centered_spaced",
s_paragraph(alignment = "center",
spacing = s_spacing(before = "6pt", after = "6pt")))
# Right-aligned with left indent
spec <- add_style(spec, id = "right_indented",
s_paragraph(alignment = "right",
indents = s_indents(left = "10pt")))s_spacing() — Line and paragraph spacingControls spacing before a paragraph, after a paragraph, and between lines.
Parameters:
before: Space before paragraph (e.g., “6pt”,
“12pt”)
after: Space after paragraph (e.g., “6pt”,
“12pt”)
line_spacing: Line spacing multiplier (e.g., 1.0,
1.5, 2.0 for single/1.5-line/double spacing)
Note: s_spacing() is always used
inside s_paragraph(), never
standalone.
Example:
s_indents() — IndentationControls left/right margins and first-line indentation within a paragraph.
Parameters:
left: Left indent (e.g., “10pt”, “1cm”)
right: Right indent (e.g., “10pt”)
first_line: First-line indent (e.g., “20pt” for
hanging indent)
Note: s_indents() is always used
inside s_paragraph(), never
standalone.
Example:
spec <- create_table(mtcars)
# Hanging indent (first line outdented, rest indented)
spec <- add_style(spec, id = "hanging_indent",
s_paragraph(indents = s_indents(left = "20pt", first_line = "-20pt")))
# Left and right margins with left indent
spec <- add_style(spec, id = "block_indent",
s_paragraph(indents = s_indents(left = "30pt", right = "30pt")))s_table_style() — Table cell propertiesControl cell background, row height, vertical alignment, text orientation, and borders.
Parameters:
background_color: Cell background color (hex, e.g.,
“#E8E8E8”)
row_height: Height of table row (e.g.,
“25pt”)
topEmptyLine: Optional empty spacer row after header
(e.g., “6pt”, use NULL or 0pt to
disable)
bottomEmptyLine: Optional empty spacer row before
the bottom border (e.g., “6pt”, use NULL or
0pt to disable)
vertical_alignment: “top”, “center”,
“bottom”
text_orientation: “horizontal”, “vertical_90”,
“vertical_270”
borders: Border specification (use
s_borders(...))
Example:
spec <- create_table(mtcars)
# Light gray background, centered vertically, fixed row height
spec <- add_style(spec, id = "header_cell",
s_table_style(background_color = "#F2F2F2",
row_height = "30pt",
vertical_alignment = "center"))
# Vertically rotated text (90 degrees)
spec <- add_style(spec, id = "rotated_header",
s_table_style(text_orientation = "vertical_90"))
# Add table-level spacer rows via set_document()
spec <- set_document(
spec,
topEmptyLine = "6pt",
bottomEmptyLine = "6pt"
)s_borders() — Border specificationsDefine borders for all four sides of a cell. Each side takes
s_border() with line style, width, and color.
Parameters (each side):
top: Top border (use
s_border(...))
bottom: Bottom border (use
s_border(...))
left: Left border (use
s_border(...))
right: Right border (use
s_border(...))
Note: s_borders() can be used
inside s_table_style() for cell-level
borders, or inside s_paragraph() for
paragraph-level borders.
s_border() — Individual border lineDefines a single border line with style, width, and color.
Parameters:
color: Color as hex code (e.g., “#000000”) or color
name (e.g., “black”, “red”)
width: Line width (e.g., “1pt”, “2pt”,
“0.5pt”)
line_style: “single”, “double”, “dashed”, “dotted”,
“thick”, “none”
Example:
spec <- create_table(mtcars)
# All borders: thin single lines in dark gray
spec <- add_style(spec, id = "all_borders",
s_table_style(
borders = s_borders(
top = s_border(color = "grey40", width = "1pt", line_style = "single"),
bottom = s_border(color = "grey40", width = "1pt", line_style = "single"),
left = s_border(color = "grey40", width = "1pt", line_style = "single"),
right = s_border(color = "grey40", width = "1pt", line_style = "single")
)
)
)
# Heavy bottom border in dark color (using hex code)
spec <- add_style(spec, id = "bottom_border_heavy",
s_table_style(
borders = s_borders(
bottom = s_border(color = "#333333", width = "2pt", line_style = "thick")
)
)
)MS Word distinguishes between cell borders
(<w:tcBorders>) and paragraph borders
(<w:pBdr>). Cell borders always span the full cell
width, while paragraph borders follow the text within the cell. This is
particularly useful for spanning headers where a cell border would
stretch across all merged columns, but a paragraph border only
underlines the header label.
Paragraph borders are set via s_borders() inside
s_paragraph():
demo <- data.frame(
trt_a = c(12, 15), trt_b = c(14, 13), age = c(45, 52), sex = c("M", "F"),
stringsAsFactors = FALSE)
spec <- create_table(demo)
# Paragraph bottom border — underlines only the text, not the full cell
spec <- add_style(spec, id = "span_underline",
s_font(bold = TRUE),
s_paragraph(
alignment = "center",
borders = s_borders(
bottom = s_border(color = "#000000", width = "0.5pt", line_style = "single")
)
)
)
# Apply to a spanning header
spec <- add_span_header(spec,
cols = c("trt_a", "trt_b"),
label = "Treatment Arms",
stubOrder = 1,
labelStyleRef = "span_underline"
)
# Combine paragraph border atom with other styles
# (disjoint column set, so it can share stubOrder = 1 with the band above)
spec <- add_span_header(spec,
cols = c("age", "sex"),
label = "Demographics",
stubOrder = 1,
labelStyleRef = f_combine("b", "ac", "pb_th")
)Key difference: structural borders — template keys
tableStyle.structural.header_top_border /
header_bottom_border — replace the header row’s CELL
borders outright and always win over labelStyleRef
cell-border atoms. Paragraph borders (the
pb/pb_th atoms, OOXML
<w:pBdr>) live in the paragraph itself and are
untouched by that override, which is why the spanning-header underline
trick above survives templates with bold header rules.
add_style()Named styles are the foundation of the ksTFL styling system. Each
style has a unique id and contains one or more style
primitives.
spec <- create_table(mtcars)
spec <- add_style(spec, id = "style_name",
s_font(bold = TRUE),
s_paragraph(alignment = "center"),
s_table_style(background_color = "#EFEFEF")
)Parameters:
spec: A TFL_spec object
id: Unique name for the style (e.g., “header_bold”,
“numeric_right”)
...: One or more style primitives
(s_font(), s_paragraph(),
s_table_style(), etc.)
spec <- create_table(mtcars)
# Comprehensive header style: bold white text on gray background, centered
spec <- add_style(spec, id = "table_header",
s_font(font_name = "Arial", font_size = "12pt", bold = TRUE, color = "#FFFFFF"),
s_paragraph(alignment = "center", spacing = s_spacing(before = "6pt", after = "6pt")),
s_table_style(background_color = "#333333", row_height = "30pt", vertical_alignment = "center")
)
# Simple numeric style: right-aligned
spec <- add_style(spec, id = "numeric_right",
s_paragraph(alignment = "right")
)
# ID/key style: bold
spec <- add_style(spec, id = "id_bold",
s_font(bold = TRUE)
)Calling add_style() multiple times with the same
id merges the styles: a later call overrides only the
properties it sets — everything else is preserved. For conflict
resolution inside f_combine(), see below.
spec <- create_table(mtcars)
# First call: defines font
spec <- add_style(spec, id = "emphasis", s_font(bold = TRUE))
# Second call: adds paragraph alignment; bold is preserved
spec <- add_style(spec, id = "emphasis", s_paragraph(alignment = "center"))
# Result: "emphasis" has both bold font AND center alignmentOnce you declare styles with add_style(), reference them
by id in various places:
labelStyleRef in
define_cols()Apply styles to column header labels:
spec <- create_table(mtcars)
spec <- add_style(spec, id = "header_bold", s_font(bold = TRUE, font_size = "12pt"))
spec <- add_style(spec, id = "header_italic", s_font(italic = TRUE))
# Apply to single column
spec <- define_cols(spec, mpg, label = "MPG (miles/gallon)", labelStyleRef = "header_bold")
# Apply to multiple columns with recycling
spec <- define_cols(spec, c(hp, cyl), label = c("HP", "Cylinders"), labelStyleRef = "header_bold")
# Different styles for different columns
spec <- define_cols(spec, c(mpg, hp),
label = c("MPG", "HP"),
labelStyleRef = c("header_bold", "header_italic"))valueStyleRef in
define_cols()Apply styles to data values in a column:
labelStyleRef in
add_span_header()Apply styles to stub (spanning header) labels:
styleRef in add_title(),
add_footnote()Apply styles to titles, subtitles, footnotes:
spec <- create_table(mtcars)
spec <- add_style(spec, id = "title_style",
s_font(bold = TRUE, font_size = "14pt"),
s_paragraph(alignment = "center"))
spec <- add_title(spec, "Motor Trends Analysis", styleRef = "title_style")f_combine()f_combine() lets you apply multiple styles to a single
element without pre-defining a combined style. When two combined styles
set the same property, the LAST argument wins — so
f_combine("b", "nrm") is not bold, and
f_combine("nrm", "b") is. Argument order is semantic.
spec <- create_table(mtcars)
spec <- add_style(spec, id = "bold", s_font(bold = TRUE))
spec <- add_style(spec, id = "red", s_font(color = "red")) # Using color name
spec <- add_style(spec, id = "centered", s_paragraph(alignment = "center"))
# Apply bold + red + centered to a column header
spec <- define_cols(spec, mpg, label = "MPG",
labelStyleRef = f_combine("bold", "red", "centered"))f_combine() vs named styles| Use Case | Approach |
|---|---|
| Reusable style (used in 3+ places) | Define a named style with add_style() |
| One-off combination (used once or twice) | Use f_combine() inline |
| Complex style (many properties) | Define named style, then optionally combine with others |
| Per-column variations | Use f_combine() with per-column vectors |
Apply different combinations to different columns:
spec <- create_table(mtcars)
# Define base styles
spec <- add_style(spec, id = "bold", s_font(bold = TRUE))
spec <- add_style(spec, id = "italic", s_font(italic = TRUE))
spec <- add_style(spec, id = "centered", s_paragraph(alignment = "center"))
spec <- add_style(spec, id = "right", s_paragraph(alignment = "right"))
# Apply different combinations per column
spec <- define_cols(spec, c(mpg, cyl, hp),
label = c("MPG", "Cylinders", "HP"),
labelStyleRef = c(
f_combine("bold", "centered"), # mpg: bold + centered
f_combine("italic", "right"), # cyl: italic + right
f_combine("bold", "italic", "centered") # hp: bold + italic + centered
)
)| Parameter family | Accepted units |
|---|---|
Font size (s_font(font_size = ...)) |
pt only |
Border width (s_border(width = ...)) |
pt only |
Paragraph spacing (s_spacing) |
pt, cm, in,
mm |
Indents (s_indents), margins
(p_margins) |
in, cm, mm,
pt |
Row height (row_height) |
pt, in, cm, mm,
or "auto" |
Spacer rows
(topEmptyLine/bottomEmptyLine) |
pt, in, cm,
mm |
Column widths (colWidth), content width
(contentWidth) |
%, in, cm |
Figure sizes
(figureWidth/figureHeight) |
%, in, cm, mm,
pt |
Color parameters accept both hex codes (e.g.,
"#FF0000") and named colors:
Basic colors: black, white, red, green, blue, yellow, orange, purple, pink, brown, gray/grey (medium, #808080), cyan, magenta, navy, teal, lightblue, lightgreen, lightred, lime, maroon, olive, silver, gold, coral, salmon, turquoise, violet, indigo, khaki, lavender, plum, tan
Grayscale: grey10 through grey90 in steps of 10 (or gray with ‘a’)
These are the exact names the font resolver accepts; which of them
are physically available on your machine is shown by
tfl_font_status() (missing faces fall back — see the Font Management vignette).
demo <- data.frame(
PARAM = c("Systolic BP", "Diastolic BP", "Pulse Rate"),
N = c(96, 96, 95), MEAN = c(128.4, 78.1, 72.6),
stringsAsFactors = FALSE)
spec <- create_table(demo)
spec <- add_style(spec, id = "clinical_header",
s_font(font_name = "Arial", font_size = "11pt", bold = TRUE, color = "#FFFFFF"),
s_paragraph(alignment = "center"),
s_table_style(background_color = "#003366", row_height = "28pt", vertical_alignment = "center")
)
spec <- define_cols(spec, c(PARAM, N, MEAN), labelStyleRef = "clinical_header")demo2 <- data.frame(age = 45, weight = 70.5, dose = 250)
spec <- create_table(demo2)
spec <- add_style(spec, id = "numeric_format",
s_font(font_name = "Courier New", font_size = "10pt"),
s_paragraph(alignment = "right")
)
spec <- define_cols(spec, c(age, weight, dose), type = "numeric", valueStyleRef = "numeric_format")demo3 <- data.frame(subject_id = c("S001", "S002"), age = c(45, 52))
spec <- create_table(demo3)
spec <- add_style(spec, id = "id_column",
s_font(bold = TRUE, font_size = "11pt"),
s_paragraph(alignment = "left")
)
spec <- define_cols(spec, subject_id,
label = "Subject ID",
labelStyleRef = "id_column",
colWidth = "15%",
isID = TRUE)demo4 <- data.frame(var1 = 1, var2 = 2, var3 = 3)
spec <- create_table(demo4)
spec <- add_style(spec, id = "level1_stub",
s_font(bold = TRUE, font_size = "12pt", color = "#FFFFFF"),
s_table_style(background_color = "#666666", vertical_alignment = "center"))
spec <- add_style(spec, id = "level2_stub",
s_font(bold = TRUE, font_size = "11pt"),
s_table_style(background_color = "#CCCCCC", vertical_alignment = "center"))
# The umbrella band gets the HIGHER stubOrder -> renders above the sub-group
# band (stacking order decides, not column width)
spec <- add_span_header(spec, cols = c("var1", "var2"), label = "Safety",
stubOrder = 1, labelStyleRef = "level2_stub")
spec <- add_span_header(spec, cols = c("var1", "var2", "var3"), label = "Baseline",
stubOrder = 2, labelStyleRef = "level1_stub")Problem: You used an s_* helper outside
add_style().
Problem: You used an invalid parameter value (e.g., “bolded” instead of TRUE).
create_report()Problem: If you used f_combine(), you
must call create_report() before the styles are
consolidated.
# Style ids referenced via f_combine() MUST exist in the spec; otherwise
# create_report() aborts with "Referenced styles not found in spec".
spec <- create_table(mtcars) |>
add_style(id = "bold", s_font(bold = TRUE)) |>
add_style(id = "red", s_font(color = "red")) |>
define_cols(mpg, labelStyleRef = f_combine("bold", "red"))
# create_report() consolidates "bold" + "red" into one resolved style
report <- create_report(spec)
write_doc(report, name = "out", outDir = "./output", metaPath = tempdir())Problem: the same property is set at several layers and a higher layer wins.
Solution: check the cascade — for one property, the
row action (c_style) beats your styleRef,
which beats the template row defaults, which beat the region style.
Structural header borders always win over cell-border atoms on header
rows; switch to the paragraph atoms (pb,
pb_th) instead. When a property still will not move,
save_report() the spec and inspect the resolved style
JSON.
create_report()When you call create_report(), the package:
1. Collects all specs
2. For each spec, finds all style references used with
f_combine()
3. Merges those combined styles into single consolidated styles
4. Generates unique hash-based names for consolidated styles
5. Updates all references to point to the consolidated style
You don’t need to inspect or manipulate
spec$attribs$styles — the consolidation is automatic and
transparent.
Every style name — whether you passed an id to
add_style() or an atom like "b",
"tw_80", "grp_hdr" — resolves against the
spec’s single style table, which starts pre-populated with the built-in
atoms. Defining add_style() with an atom’s name shadows the
built-in. An unresolved name, user style or atom alike, aborts
create_report() with “Referenced styles not found in spec”
and lists the missing ids.
ksTFL ships a library of single-property style atoms accessible via
f_combine() or directly as styleRef values.
Each atom sets exactly one visual property; compose them freely with
f_combine().
Discovering atoms programmatically: Use
tfl_print_style_atoms() (or its alias
tfl_style_atoms_catalog()) to print all available atoms
grouped by category with colour-coded output in the console:
| Atom | Effect |
|---|---|
| Font — decoration | |
b / font_bold |
Bold |
i / font_italic |
Italic |
u / font_underline |
Underline |
| Font — family | |
font_arial |
Set font_name = "Arial" |
font_courier_new |
Set font_name = "Courier New" |
font_times_new_roman |
Set font_name = "Times New Roman" |
font_georgia |
Set font_name = "Georgia" |
font_verdana |
Set font_name = "Verdana" |
font_trebuchet_ms |
Set font_name = "Trebuchet MS" |
| Font — size | |
fs_7 … fs_12 |
Font size 7 pt … 12 pt |
| Font — colour | |
fc_black, fc_red, fc_blue,
fc_green |
Pure text colours |
fc_gray / fc_grey |
Secondary / reference text (#595959) |
fc_navy, fc_teal, fc_olive,
fc_rust, fc_plum, fc_slate |
Muted clinical palette |
| Text highlight (cell shading) | |
hl_yellow, hl_red, hl_green,
hl_gray / hl_grey |
Strong highlight colours |
hl_peach, hl_mint, hl_sky,
hl_lemon, hl_lilac |
Pastel highlight palette |
| Paragraph — alignment | |
al / text_left |
Left-align |
ar / text_right |
Right-align |
ac / text_center |
Center-align |
| Paragraph — left indentation | |
ind0 / indent_0 |
No indent (reset to left margin) |
ind1 / indent_1 |
0.5 cm left indent (top-level category) |
ind2 / indent_2 |
1.0 cm left indent (first sub-group) |
ind3 / indent_3 |
1.5 cm left indent (second sub-group) |
ind4 / indent_4 |
2.0 cm left indent (detail) |
| Paragraph — right indentation | |
rind0 / rindent_0 |
No right indent (reset to right margin) |
rind1 / rindent_1 |
0.5 cm right indent |
rind2 / rindent_2 |
1.0 cm right indent |
rind3 / rindent_3 |
1.5 cm right indent |
rind4 / rindent_4 |
2.0 cm right indent |
| Paragraph — table-width shrink | |
tw_95 … tw_50 |
Symmetric left+right indent to match table at 95 %…50 % width (5 % steps) |
| Paragraph — spacing | |
sp_0 |
No space before/after paragraph |
sp_2 |
2 pt space before and after |
sp_4 |
4 pt space before and after |
| Paragraph — pagination | |
kl |
Keep all lines of a cell on the same page |
kn |
Keep this row on the same page as the next row |
| Group / category header composites | |
grp_hdr |
Bold + 4 pt space above + left indent reset (category header) |
grp_hdr_i |
Bold + italic + 4 pt space above + left indent reset |
| Cell — vertical alignment | |
va_t / va_top |
Top |
va_m / va_center |
Middle |
va_b / va_bottom |
Bottom |
| Cell — text orientation | |
to_h / text_horizontal |
Horizontal (default) |
to_90 / text_vertical_90 |
Rotated 90° (bottom-to-top) |
to_270 / text_vertical_270 |
Rotated 270° (top-to-bottom) |
| Cell — background colour | |
bg_blue, bg_gray /
bg_grey |
Standard backgrounds |
bg_peach, bg_mint, bg_sky,
bg_lemon, bg_lilac |
Pastel backgrounds |
bg_navy, bg_slate,
bg_steel |
Dark/medium header backgrounds |
| Row height | |
row_h2, row_h4, row_h6 |
Row height 2 / 4 / 6 pt (separator rows) |
| Border — sides (1 pt black) | |
bt, bb, bl,
br |
Top / bottom / left / right border |
| Border — thin sides (0.5 pt black) | |
bt_th, bb_th |
Thin top / bottom border |
| Border — colour override | |
bc_gray / bc_grey |
All sides → medium gray (#AAAAAA) |
bc_white |
All sides → white / none (suppress borders) |
| Border — thick white sides (column separation) | |
brw_thick |
Right border 4 pt white (visual column gap) |
blw_thick |
Left border 4 pt white (visual column gap) |
| Paragraph border — bottom | |
pb |
Paragraph bottom border 1 pt black |
pb_th |
Paragraph bottom border 0.5 pt black (thin) |
Usage:
demo5 <- data.frame(group = c("A", "A", "B"), value = c(1.5, 2.7, 3.1),
stringsAsFactors = FALSE)
spec <- create_table(demo5)
# Single atom as styleRef
spec <- add_footnote(spec, "Source: database.", styleRef = "fs_8")
# Combine atoms with f_combine()
spec <- define_cols(spec, value,
valueStyleRef = f_combine("font_verdana", "ar", "fs_9"))
# Combine atoms with named styles
spec <- add_style(spec, id = "group_hdr",
s_font(bold = TRUE),
s_paragraph(spacing = s_spacing(before = "4pt")))
spec <- compute_cols(spec, firstOf(group),
c_style(everything(), styleRef = f_combine("group_hdr", "bg_gray")))tw_*)When a table is narrower than the full content width, titles,
subtitles, footnotes, and body text will span the full page width by
default — wider than the table itself. The tw_* atoms apply
symmetric left and right paragraph indentation so that text blocks
visually align with the table edges.
Indent values are calculated for A4 landscape with 0.5 in left/right page margins (content width ≈ 27.16 cm). Each 5 % step corresponds to 0.68 cm per side.
| Atom | Table width | Indent each side |
|---|---|---|
tw_95 |
95 % | 0.68 cm |
tw_90 |
90 % | 1.36 cm |
tw_85 |
85 % | 2.04 cm |
tw_80 |
80 % | 2.72 cm |
tw_75 |
75 % | 3.40 cm |
tw_70 |
70 % | 4.07 cm |
tw_65 |
65 % | 4.75 cm |
tw_60 |
60 % | 5.43 cm |
tw_55 |
55 % | 6.11 cm |
tw_50 |
50 % | 6.79 cm |
Usage — match footnotes and titles to a narrower table:
spec <- create_table(mtcars) |>
set_document(contentWidth = "80%") |>
add_title("Demographics Table", styleRef = "tw_80") |>
add_subtitle("Safety Population", styleRef = "tw_80") |>
add_footnote("Source: study database.", styleRef = "tw_80")Combine with other atoms using
f_combine():
spec <- create_table(mtcars)
# Bold title, indented to match a 75 % table
spec <- add_title(spec, "Efficacy Summary",
styleRef = f_combine("b", "tw_75"))
# Small italic footnote, indented to match a 70 % table
spec <- add_footnote(spec, "Values are least-squares means.",
styleRef = f_combine("i", "fs_8", "tw_70"))Apply via a named style for reuse across multiple specs:
spec1 <- create_table(mtcars)
spec2 <- create_table(iris)
# Define the style on each spec (or use a helper function to apply it)
add_footnote_80 <- function(spec, text) {
spec <- add_style(spec, id = "fn_80",
s_font(font_size = "8pt", italic = TRUE),
s_paragraph(alignment = "left",
indents = s_indents(left = "2.72cm", right = "2.72cm")))
add_footnote(spec, text, styleRef = "fn_80")
}
spec1 <- add_footnote_80(spec1, "a. p < 0.05")
spec2 <- add_footnote_80(spec2, "b. LOCF imputation")Note: The indent values assume the default A4 landscape page with 0.5 in margins. If you use a different page size, orientation, or margins via
set_page_style(), calculate your own indents withs_indents(left = ..., right = ...)insideadd_style().
?add_style,
?s_font, ?s_paragraph,
?f_combineadd_style()f_combine()