Public/Save-VellumPdfDocument.ps1
|
function Save-VellumPdfDocument { <# .SYNOPSIS Writes a VellumPdf document to a .pdf file and disposes it. .DESCRIPTION Wraps Document.Save(path). The document is IDisposable; this function disposes it after the save attempt (success or failure) because saving is the terminal step of a build pipeline, and marks it so later cmdlet calls against the stale document fail with a clear error. Use -KeepOpen to keep the document alive for further edits, in which case you are responsible for calling $doc.Dispose() yourself. With -WhatIf nothing is saved and the document is left open. If the pipeline is aborted BEFORE this cmdlet runs (for example by an error in an earlier Add-VellumPdf* call, or -WarningAction Stop turning the encoding warning into a terminating error), the document is never saved or disposed - dispose it yourself in your catch block. An existing file at -Path is overwritten. .PARAMETER Document The live VellumPdf document to save. Accepts pipeline input. After saving, the document is disposed and stamped so subsequent cmdlet calls against the stale instance fail with a clear error. Use -KeepOpen to suppress disposal. .PARAMETER Path File system path for the output PDF file. The parent directory must already exist; an existing file at this path is overwritten. Mandatory and positional (position 0). .PARAMETER KeepOpen When specified, the document is not disposed after saving. The caller is responsible for calling $doc.Dispose() when finished. Useful when the same document object must be inspected or further manipulated after the file is written. .EXAMPLE $doc | Save-VellumPdfDocument -Path ./out.pdf .OUTPUTS System.IO.FileInfo for the written file. #> [CmdletBinding(SupportsShouldProcess)] [OutputType([System.IO.FileInfo])] param( [Parameter(Mandatory, ValueFromPipeline)] [VellumPdf.Layout.Document]$Document, [Parameter(Mandatory, Position = 0)] [string]$Path, # Keep the document open after saving (caller must Dispose it). [switch]$KeepOpen ) process { Assert-VellumPdfDocumentOpen -Document $Document -CommandName 'Save-VellumPdfDocument' $resolved = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($Path) $attempted = $false try { $parent = [System.IO.Path]::GetDirectoryName($resolved) if ($parent -and -not [System.IO.Directory]::Exists($parent)) { $attempted = $true throw "Save-VellumPdfDocument: directory not found: '$parent'. Create it first or pass a path in an existing directory." } if ($PSCmdlet.ShouldProcess($resolved, 'Save PDF')) { $attempted = $true try { $Document.Save($resolved) } catch { # Surface layout/render failures with actionable context # instead of a bare library exception. $reason = $_.Exception.Message if ($_.Exception.InnerException) { $reason = $_.Exception.InnerException.Message } throw ("Save-VellumPdfDocument: failed to render '$resolved': $reason " + 'Check for extreme margin values or elements taller than the page.') } Get-Item -LiteralPath $resolved } } finally { # Dispose after any save attempt (success or failure), but leave the # document open under -WhatIf, where no attempt was made. The stamp # lets the other cmdlets reject stale use of this document (VellumPdf # itself accepts Add() on a disposed document without complaint). if ($attempted -and -not $KeepOpen) { $Document.Dispose() if (-not $Document.PSObject.Properties['PSVellumDisposed']) { $Document.PSObject.Properties.Add([psnoteproperty]::new('PSVellumDisposed', $true)) } } } } } |