Repository navigation
Papercut 0.6.0
Pre-release
Pre-release
Added
- Laravel: a
PendingOutputorPendingHtmlcan be attached to a mailable or notification with->attach(...). The document renders when it is attached, and the attachment is nameddocument.pdf,document.docxordocument.html.PendingOutput::attachment('name.pdf')sets the name (cleaned likedownload()) without rendering;PendingHtmlattaches the full page.PapercutManager,PendingDocument,PendingOutputandPendingHtmlareMacroable. Span::code($text)andText::code($text): inline code in PHP, a literal span in thecodestyle, the same as<x-doc::code>and<code>in markup.- PHP setters that take an option also take its string value, matched without regard to case or surrounding spaces:
direction,justifyandalignonView,RowandColumn;alignSelf,textAlignand the style argument ofborder;TableCell::align,Image::fit,ListNode::marker,Place::anchor, andQrCode::make(the level),errorCorrection,shape,eyesandgradient(the type). A case name also matches, so'high'isErrorCorrection::High.->align('center')now works as in Blade; an unknown string throwsInvalidValuewith a suggestion. - Other names for the anchors in the middle of each side:
top-center,bottom-center,center-leftandcenter-rightas strings and in Blade'sanchor, andAnchor::TopCenter,Anchor::BottomCenter,Anchor::CenterLeftandAnchor::CenterRightin PHP. They are the same cases asTop,Bottom,LeftandRight.<x-doc::place anchor>now also ignores case and suggests the closest name for a typo. - A
guideexample (examples/core/documents/guide.phpandexamples/laravel/views/guide.blade.php): a three-page API integration guide on US Letter, portrait then landscape then portrait, with syntax-highlighted code blocks, badges in a table, a QR code and a go-live checklist. - A
certificateexample (examples/core/documents/certificate.phpandexamples/laravel/views/certificate.blade.php): a name, course, date and signature image placed on a blank US Letter landscape PDF template, built byexamples/core/certificate-template.php. It is PDF only, because Word and HTML exports leave page templates out. - An
articleexample (examples/core/documents/article.phpandexamples/laravel/views/article.blade.php): a two-page knowledge base article on A4, made from the HTML a rich text editor saves, with PDF, HTML and Word output. - Tables of contents:
Toc::make()->levels(1, 3)->title('Contents')->leaders(false)in PHP and<x-doc::toc levels="1-3" title="Contents" :leaders="false" />in Blade. Entries are theh1toh4headings (default levels 1 to 2), each with its physical page number and dot leaders, and a link to the heading in the PDF.->toc(false)/toc="false"leaves a heading out;bookmark('Short')sets the entry's text andbookmark($title, $level)its level. Styled by the named stylestoc,toc.title,toc.entryandtoc.level-1totoc.level-4. Word export writes a real TOC field filled in with the PDF's page numbers (Update Field in Word renumbers it; an updated field reads Heading 1 to 4, sotoc(false)and bookmark levels aren't honoured then), and runs the PDF layout for documents that have one (if that layout can't run, the field is written without page numbers and the export still succeeds). HTML export writes a<nav class="papercut-toc">of links without page numbers, reported as approximated. A table of contents in a header, footer, background or overlay throwsInvalidStructure. - The report example has a table of contents (PDF, Word and HTML outputs regenerated).
- Laravel:
PendingOutput::streamDownload('name.pdf')returns the download as a streamed response, named likedownload(), that renders the document when it is sent. Livewire actions, and so Filament actions, send files only from streamed or file responses, sodownload()does nothing there andstreamDownload()works. - A Laravel recipes page in the docs: storing on S3 or any disk, making documents in a queued job, emailing them, downloading from Livewire or Filament, and drawing charts as SVG from a Blade component.
- Theme overrides per document and per page. In PHP,
Document::theme(new ThemeOverride(...))andPage::theme(...)set font family, size, weight, colour, line height, cell padding, minimum lines, mono family, code theme and named styles for one document or page;Theme::withOverride()does the merge. In Blade,<x-doc::document :theme="[...]">and<x-doc::page :theme="[...]">;PendingDocument::theme([...])from a controller. Order: config, the view's document, the controller, then the page. Named styles in an override merge onto the existing style. PDF lays out each page with its theme, HTML writes the page's differences on its section, and Word writes the document theme as Word's defaults and page values on that page's paragraphs. - Named styles
h1toh4style headings of that level at every theme level (Theme::withStyle(),papercut.styles, overrides). Layering: the built-in heading look, the theme'sh<n>style, the node's own style name, then its own style. - A page or document code theme (
codeThemein PHP,code_themein Laravel) is the default for code blocks that don't name a theme.
Changed
- Laravel: unknown keys in
papercut.themenow throw instead of being ignored. Onlyfont_family,mono_family,font_size,colorandline_heightare read there; the error names the key and pointscode_themetopapercut.code.themeandstylestopapercut.styles. - Breaking: a custom style named
h1,h2,h3orh4now applies to headings of that level. Without one, headings look as before. - Word export (
papercut/docx) is no longer labelled experimental. It is versioned with core and Laravel, and follows the same compatibility rules. Word, LibreOffice and Google Docs still lay out the file themselves, so page breaks can differ from the PDF. - Breaking:
Spacer::size($length)is nowSpacer::fixed($length). The static factory hid thesize()modifier every other node has, so$spacer->size(pt(9))quietly made a new spacer and dropped its grow and background. On a spacer,->size()now sets the gap and keeps the rest of its style. Blade's<x-doc::spacer size="...">is unchanged. - Custom
Backendimplementations must handle the newPapercut\Paint\Anchorop. It draws nothing and marks a named destination for a table of contents entry; it only appears in documents that have a table of contents. InvalidStructuremoved to core asPapercut\Exception\InvalidStructure.Papercut\Laravel\Exception\InvalidStructurenow extends it, so existingcatchblocks keep working.- The guide example uses
Text::code()for inline code and one string option (->align('center')). - The docs say that
columns()accepts any length unit, and list the code block language aliases (bash,sh,shellandzshfor shell,js,ts,py,yml). - The README, the Laravel package description and the social preview image name all three formats (PDF, Word, and HTML); core's description names PDF and HTML. The guide's limitations say "fillable form fields (AcroForms)" instead of "form filling", since filling in an existing PDF works, and the HTML export page says backgrounds and overlays are approximate.
- The invoice and transcript examples use US Letter and inches instead of A4 and millimetres, so the examples show both (the report and form responses stay on A4). The transcript now runs to three pages.
Fixed
- Invisible formatting characters (soft hyphens, zero-width joiners and spaces, direction marks, word joiners, byte order marks), common in text pasted from Word or a CMS, are no longer drawn as empty boxes in PDF. The line and paragraph separators (U+2028, U+2029) count as newlines.
- Strict mode throws
UnsupportedFeaturewhen a printed page of a PDF has characters no font has, in text or SVG text, naming the page and the characters. They print as empty boxes, and before only a warning said so, which plain PHP drops unless you passonWarning. The fonts guide has a new section on fallback fonts for names in other scripts, and says that a short right-to-left run, such as an Arabic or Hebrew name, already lays out correctly. - Content taller than its box's
heightormax-heightno longer draws over what follows without a word. It follows the overflow mode, as content too tall for a page does: Throw mode throwsLayoutOverflownaming the box, and Clip mode clips it to the box and warns. Documents whose boxes overflowed now throw in Throw mode (Laravel's default inlocalandtesting) or come out clipped. papercut/laravelandpapercut/docxrequirepapercut/core^0.6(and Laravel's dev requirement onpapercut/docxis^0.6); they still asked for^0.5, which no 0.6 core satisfies.- A release candidate tag (
v1.0.0-rc.1, any version with a-) is published as a GitHub pre-release. - A table row too tall for one page, split just below the header, no longer paints its first line past the bottom of the page when that line doesn't fit below the header. This includes rows with spanning cells and tables inside table cells. A repeated header is left out on that page instead; on the first page the header stands alone and the rows start on the next page, with a warning.