From b35c136f7fdf4c718aa5b3b8a04ce6914ae0504f Mon Sep 17 00:00:00 2001 From: "russell@unturf.com" Date: Sat, 25 Apr 2026 16:26:21 -0400 Subject: [PATCH] feat: side-by-side provenance header (text left, QR right) Wraps the provenance header in an HTML table so the source/snapshot/ generator block sits left and the QR sits right at the same horizontal level. Pandoc converts the table cleanly into native table cells across HTML, PDF (wkhtmltopdf), DOCX, ODT, EPUB. Without a QR (qr_data_uri=None) we fall back to the plain blockquote. --- remarkbox/lib/provenance.py | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/remarkbox/lib/provenance.py b/remarkbox/lib/provenance.py index 5c54f3d..952328f 100644 --- a/remarkbox/lib/provenance.py +++ b/remarkbox/lib/provenance.py @@ -93,24 +93,39 @@ def header_md(canonical_uri, snapshot_iso=None, version="dev", qr_data_uri: Result of `qr_png_data_uri`; if None, no QR rendered. kind: "thread", "namespace", "subthread" — used in the snapshot caption. - Returns markdown intended to sit at the very top of a document. Pandoc - propagates this verbatim into HTML, then through wkhtmltopdf for PDF. + Returns markdown intended to sit at the very top of a document. When a QR + is present we lay out text on the left and QR on the right via an HTML + table; pandoc converts the table cleanly into HTML, PDF (wkhtmltopdf), + DOCX, ODT, EPUB native table cells. Without a QR we fall back to a plain + blockquote. """ if snapshot_iso is None: snapshot_iso = _utc_now_iso() - lines = [ + text_lines = [ "> **Source:** [{}]({}) ".format(canonical_uri, canonical_uri), "> **Snapshot:** {} ".format(snapshot_iso), "> **Generator:** Remarkbox `{}` ".format(version), ">", "> *This is a {} snapshot. The living document lives at the source URI above — it may have been edited, extended, or replied-to since.*".format(kind), - "", ] - if qr_data_uri: - lines.append("![Scan to visit the living source]({})".format(qr_data_uri)) - lines.append("") - return "\n".join(lines) + + if not qr_data_uri: + return "\n".join(text_lines + [""]) + + text_block = "\n".join(text_lines) + return ( + '\n' + '\n' + '\n' + '\n' + '\n' + '
\n\n' + '{text}\n\n' + '\n\n' + '![Scan to visit the living source]({qr})\n\n' + '
\n' + ).format(text=text_block, qr=qr_data_uri) def footer_md(canonical_uri, snapshot_iso=None, version="dev"):