Check a .docx for structural patterns the house rules forbid
Source:R/hv-check-docx.R
hv_check_docx.RdRead-only inspection of any Word document, whether written by this package or received from elsewhere. Reports the three structural failure patterns the canonical "Table Construction for Manuscripts" memo names, a table too wide for its page, and markup left as plain text, and never modifies the file.
Arguments
- path
Path to a
.docxfile.- style
NULL, the default, applies the rule every style shares. A style name orhv_table_style()applies that style's rule: the report style merges no cells at all.
Value
A data.frame with one row per finding and columns type,
table (1-indexed table number, NA when document-level),
location (row/column detail where applicable, NA otherwise), and
detail (human-readable description). Zero rows means clean.
Details
Six detectors run:
"layer"(structural, high confidence): paragraphs positioned withw:framePr, or floating text boxes (w:txbxContent). Table content belongs in the table, not in a floating layer over it."hidden_column"(structural, high confidence): a table column that is both entirely empty and strictly narrower than 0.1 inch (aw:gridColwidth below 144 dxa; exactly 144 does not count). Both conditions are required. The house's own JTCVS templates contain all-empty 0.5-inch gutter columns between group pairs, which are deliberate; width alone or emptiness alone would flag them. A cell spanning several columns counts as filling every column it covers, so a merged header never makes the columns beneath it look empty."wide_table"(structural, high confidence): a table whose grid is wider than the text block of the page section it sits in (page width less both margins), by more than 1 pt. Word clips what runs past the margin, so the rightmost columns are lost from the page."embedded_footnote"(heuristic, lower confidence): a cell in a table's last row whose text starts with a footnote marker (*, a dagger or double dagger, a section or pilcrow sign, a lettereda./b.marker,Key:orAbbreviation:) or whose first run is a superscript number, asgtsummarywrites a footnote, the patternflextable::footnote()produces when misused. This detector is pattern-based rather than a guaranteed structural signature, so treat its findings as prompts to look, not proof."merged_cell"(structural, high confidence): a row whose cells are merged (w:gridSpanabove 1,w:vMerge, or the legacyw:hMerge) outside the header rows, unless the row is one cell spanning the table. The header rows are the leading run of rows whosew:tblHeaderflag is on, as Word reads it. Withstyle = "report", any merged cell is a finding."markup"(heuristic, lower confidence): a paragraph whose baseline text still holds^...^or~...~markup, such as"BSA (m^2^)". Raised and lowered runs are skipped, as they are the renderer's own output.hv_man_table()andhv_man_table_save()render the markup as a superscript or subscript, so markup left in the text reached Word another way, and would print as typed. It is a text pattern, so a URL such ashttp://host/~a/~balso matches. Checked whateverstyleis given.
Common mistakes
"path must be a single non-empty string." The argument is a
file path, not a flextable or an officer document. The saver
does not run this on its own output, so call it on the written .docx
afterwards.
Reading a hidden_column finding as a gutter column. It is not
one. The detector requires empty and narrower than 0.1 inch,
precisely so the deliberate half-inch gutter columns in the house
JTCVS templates do not trip it. A finding here is a real spacer.
Treating embedded_footnote or markup as proof. They are the two
heuristic detectors of the six. embedded_footnote matches a marker
character opening a cell in a table's last row, and a legitimate last
row that happens to start that way matches it too. markup matches a
pair of ^ or ~ characters, and a URL with two tildes matches it.
Read either as a prompt to look, not a verdict.
Expecting a repair. This is read-only and never modifies the
file. Fix what it reports in Word, or rebuild the table through
hv_man_table_save().
See also
hv_man_table_save(), which writes the files this checks. It does
not run the check on its own
output, so call this on the path afterwards when you want it.
Examples
tbl <- hv_tbl_summary(
gtsummary::trial, by = "trt",
groups = list(Demography = "age"),
continuous = "age", categorical = character(0), compare = "none"
)
ft <- hv_man_table(tbl, style = "manuscript", layout = "describe")
out <- tempfile(fileext = ".docx")
hv_man_table_save(ft, out, caption = "Table 1. X")
hv_check_docx(out)
#> [1] type table location detail
#> <0 rows> (or 0-length row.names)
unlink(out)