Bug fix release.
- Fixed a crash in the flow engine when a block's height equalled the space
left on the page to within floating-point error:
split()then reported the whole block as fitting (head = <block>,tail = NULL) and.place_block()went on to measure theNULLtail ("attempt to apply non-function")..place_block()now (a) treats a block as fitting when its height exceeds the remaining space by less than 1e-9 pt, matching the tolerance thesplit()methods already use, and (b) stops cleanly when a split returns no tail, instead of starting a page for it. Affectedblock_para(),block_pre()andblock_table()alike;nmwworked around it. Regression-tested ininst/tinytest/test_flow.R. .block_seq()(used byblock_table()/block_matrix()) now returnstail = NULLrather than an empty sequence block when a split consumes every sub-block, which also removes a spurious trailing blank page.
Documentation-only release for the CRAN resubmission (no code changes).
- Added the missing
\valuesections to all exported functions' help pages (CRAN review):flow_run(),flow_add(),remaining(),running_header()/running_footer(),block_keep(),block_spacer(),block_rule(),frame_set(),sp_page(),sp_close(),sp_trace(). - Expanded the existing
\valuesections to describe the structure (class) and meaning of every return value, e.g. what a "block" is (a list withmeasure/draw/keep/splitcomponents consumed by the flow engine) and that document-handle returns are environments updated in place.
First working slice of the device-based report engine (see PLAN-simPDF.md).
- Document / canvas:
sp_new()opens apdf()/cairo_pdf()device with a point coordinate system;sp_page(),sp_close(),frame_set(). - Measurement:
sp_width()/sp_height(). AFM-exact for the core fonts and linear in size for fractional sizes too (measured at a reference size and scaled, working around thepdf()device's integer font-size rounding instrwidth). - Flow engine:
flow_run()/flow_add()place measured blocks, advancing the cursor by real height and paginating automatically;block_keep()(keep-together),block_spacer(),block_rule(),remaining(),running_header()/running_footer(). - Content blocks:
block_para()(word-wrapped, aligned) andblock_pre()(monospacecapture.output()dumps, auto-shrunk to fit the frame width). - QA:
sp_trace()/sp_overlaps()record and detect overlapping text bounding boxes. Tests ininst/tinytest/assert a 200+ line synthetic report renders with zero overlap across multiple pages.
This removes the dead-reckoned-coordinate overlap of the nmw diagnostic
reports (see inst/examples/nmw_params.R).
block_table(): renders a data.frame/matrix with column widths measured from the content, numeric columns right-aligned, a header that repeats on every page, a rule under the header, and automatic row-boundary page splitting. If the natural width exceeds the frame, the font shrinks uniformly to fit. Row names become a leading label column.block_matrix(): renders a wide matrix by splitting its data columns into groups that each fit the page width (row labels repeated in every group), stacked vertically -- replacing hand-placed column loops such asPrinTxt(row, i * 8, ...)that overflow for many columns.- Tracer now records the drawn text of each box, so tests assert header-repeat
directly.
inst/tinytest/test_table.Rcovers a 200-row split table (header repeated once per page) and a 20-column matrix split into groups, both with zero overlap.
block_table/block_matrixshrink-to-fit now scales the cell padding by the same factor as the font and column widths. Previously only font and widths were scaled, so at strong shrink (tot > 2 * frameW) the last column's text spilled past the frame's right edge (and a right-aligned first column past the left). Regression-tested.- A 0-row data.frame/matrix now renders its column headers instead of a
blank band:
.tabularizepreserves the column count when there are no rows, and.natural_widthsguards the empty-columnmax()soheader = FALSE0-row input no longer warns. Regression-tested.
block_plot(expr, height): evaluates a base-R plotting expression (scatter, histogram, QQ, ...) inside a reserved band of the flowing page viapar(fig), then restores the text canvas. Plots sit inline with measured text, are kept with their headings viablock_keep, and participate in pagination. The expression is captured unevaluated and run at draw time in the caller's environment.block_image(img, height): embeds a raster, array/matrix, or PNG/JPEG file (png/jpegin Suggests) viarasterImage.- Fixed a page-desync bug found in visual verification: the canvas is now
restored with
par(op)alone (no extraplot.new()), so a page break after ablock_plotadvances the physical PDF page in lock-step withdoc$page_no. Regression-tested by comparingdoc$page_noto the physical/Type /Pagecount. Seeinst/examples/nmw_diagnostics.R.
For downstream packages that build reports on simPDF:
block_authorship()andblock_signature(): a "Prepared by" metadata block and visible approval/signature lines (role caption + dated line). The signing rectangles are recorded ondoc$sig.sp_add_sig_fields(): a finishing pass that inserts interactive Adobe Acrobat digital-signature fields (AcroForm/Sig) into the written PDF via a pure base-R incremental update (no external tools) -- generalised fromNonCompart::addSigFieldNCA, and driven by thedoc$sigrectangles so the clickable fields land exactly on the visible lines. The result is one-click-signable in the free Acrobat Reader and passesqpdf --check.block_flow_diagram(): a model-development flow diagram where each node is a box measured to its text, laid out as a tidy tree (children centred under parents) and scaled uniformly to fit the frame -- so more models shrink the diagram instead of cluttering it (unlike the dead-reckoned legacyOutline).
All 8 nmw diagnostic reports now have simPDF implementations (S2-Parameters
plus the remaining seven: S1-OFV, S3-Predictions, S4-Residuals, S5-EBE,
SA-Input, SB-Output, SC-IndiPK). Each keeps the parsing/statistics verbatim and
replaces the dead-reckoned pdf()+PrinTxt/split.screen layout with a
blocks list + flow_run() (text/tables) and sp_figure_page() (per-subject /
per-eta plot pages). Validated on the bundled 2006 example (all 8 generate)
and across real runs (97/98 report generations on 14 models); the
S3-Predictions "zero-length labels" crash on subjects with no observations is
fixed (was 11/18, now 14/14). These functions live with the nmw package
(which gains simPDF in Imports); simPDF gained sp_figure_page() to host the
full-page multi-panel diagnostic pages.
- Land the migrated
report_*functions innmw(replace bodies, drop the oldPrepPDF/PrinTxt/AddPage/PrinMTxt/ClosePDFfrompdf_report.R). - Optional pagination for very large flow diagrams (currently scale-to-fit).