Skip to content

Canvas PDF Export

The Canvas PDF is a branded, print-ready rendering of the memo exactly as it stands in the editor. It captures your prose, your charts, your images, and your citations — faithfully, in document order — and it is available at any time, in any document state. It’s the export you reach for when you want a clean copy of the working memo: to read offline, to attach to a thread, or to share for internal review before the deal is signed off.

It is distinct from the Investor Packet, which composes a separate offering document. The Canvas PDF mirrors the memo; the Investor Packet builds an offering document around it.

The PDF is rendered from the memo’s markdown through Memosa’s branded template. The pipeline preserves the parts of the memo that carry meaning:

  • A branded cover page with the deal name, a one-line investment-thesis subtitle pulled from the executive summary, and an optional hero image.
  • A table of contents built from the memo’s section headings, with each heading lifted into the PDF reader’s outline pane so you can navigate in Adobe, Preview, or Chrome.
  • Every section, paginated so each new section starts on a fresh page.
  • Charts rendered as images. Each chart is drawn to a figure with its Insight caption (the statistical takeaway) and its Decision caption (the IC question it answers) printed beneath it — the same reader-usefulness context the chart carries in Canvas. If a chart can’t be rendered, the PDF shows a visible “Chart unavailable” placeholder rather than silently dropping it.
  • Inline images hydrated into the document so the PDF is self-contained (no live network fetches at render time).
  • A dedicated endnotes page carrying the memo’s footnotes, each tagged with a source badge — User, Excel, CoStar, or PDF — so the data-source precedence behind each cited figure survives into the export.

Unlike the Investor Packet, the Canvas PDF has no approval requirement — it can be exported in Draft, Editing, or Approved. Because it’s a read-only snapshot, it’s available to any collaborator on the deal, down to Viewer access. (The Investor Packet, by contrast, requires Editor access and an approved memo.)

The filename is date-stamped (<DealName>_IC_Memo_<YYYY-MM-DD>.pdf) so successive exports don’t overwrite each other.

Every time a memo is approved, Memosa mints an immutable approval snapshot that includes the Canvas memo PDF as it was at that moment (and the Investor Packet PDF too, once you generate it). The deal’s export history lists these snapshots newest-first, and you can re-download the exact bytes from any past approval by its snapshot ID. This is what lets you approve a memo, reopen and revise it, re-approve, and still retrieve the earlier approved version verbatim.

Canvas PDFInvestor Packet
What it isThe memo, rendered faithfullyA composed offering document
State requiredAny stateApproved only
AccessViewer and upEditor and up
ContentYour prose, charts, images, footnotesDeal terms + pipeline data + memo prose + risk section + state notice
FormatBranded PDFBranded DOCX, plus a PDF rendering
Rate limit1 / minute3 / hour (shared with the deck)

Both ultimately render to PDF through the same self-hosted Gotenberg service — the Canvas PDF via Gotenberg’s HTML (Chromium) route, the Investor Packet via its DOCX (LibreOffice) route.

  • src/canvas/services/pdf_export_service.pyPdfExportService.export_to_pdf(): the full render pipeline (markdown → chart-to-image → image hydration → pymmd HTML → branded Jinja template → Gotenberg), the approval-seal logic, footnote provenance badges, and the TOC/outline handling.
  • src/canvas/routes/export_routes.py — the /export/pdf route (Viewer auth, 1-per-minute rate limit, available in any state), the export-status endpoint, and the approval-snapshot history listing.
  • src/investor_packet/pdf_converter.pyGotenbergPdfConverter.convert_html(): the Gotenberg Chromium HTML → PDF path shared by the Canvas export.
  • src/canvas/models/section_lifecycle.pyDocumentState; confirms PDF export is a stateless action that does not change document state.