Public/Export-TerminalPresentation.ps1
|
function Write-TerminalExportFile { param( [Parameter(Mandatory)][string]$Path, [Parameter(Mandatory)][AllowEmptyString()][string]$Content, [Parameter(Mandatory)][bool]$Overwrite, [AllowNull()][object]$MediaTransaction ) Assert-TerminalValidUtf16 -Value $Content $parent = Split-Path -Path $Path -Parent if (-not (Test-Path -LiteralPath $parent -PathType Container)) { [void][System.IO.Directory]::CreateDirectory($parent) } $temporaryPath = Join-Path $parent ('.' + [System.IO.Path]::GetFileName($Path) + '.' + [guid]::NewGuid().ToString('N') + '.tmp') $assetBackup = $null try { [System.IO.File]::WriteAllText($temporaryPath, $Content, [System.Text.UTF8Encoding]::new($false)) if ($MediaTransaction -and $MediaTransaction.HasAssets) { $assetBackup = Install-TerminalStagedAssets -Transaction $MediaTransaction } try { [System.IO.File]::Move($temporaryPath, $Path, $Overwrite) } catch { if ($MediaTransaction -and $MediaTransaction.HasAssets -and (Test-Path -LiteralPath $MediaTransaction.FinalDirectory)) { Remove-Item -LiteralPath $MediaTransaction.FinalDirectory -Recurse -Force -ErrorAction SilentlyContinue } if ($assetBackup -and (Test-Path -LiteralPath $assetBackup)) { Move-Item -LiteralPath $assetBackup -Destination $MediaTransaction.FinalDirectory $assetBackup = $null } throw } if ($assetBackup -and (Test-Path -LiteralPath $assetBackup)) { Remove-Item -LiteralPath $assetBackup -Recurse -Force $assetBackup = $null } } finally { if (Test-Path -LiteralPath $temporaryPath) { Remove-Item -LiteralPath $temporaryPath -Force -ErrorAction SilentlyContinue } if ($MediaTransaction -and $MediaTransaction.StagingDirectory -and (Test-Path -LiteralPath $MediaTransaction.StagingDirectory)) { Remove-Item -LiteralPath $MediaTransaction.StagingDirectory -Recurse -Force -ErrorAction SilentlyContinue } if ($assetBackup -and (Test-Path -LiteralPath $assetBackup) -and -not (Test-Path -LiteralPath $MediaTransaction.FinalDirectory)) { Move-Item -LiteralPath $assetBackup -Destination $MediaTransaction.FinalDirectory -ErrorAction SilentlyContinue } } } function Export-TerminalPresentation { [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'Medium')] param( [Parameter(Mandatory)][TerminalSlides.Schema.V1.TerminalPresentation]$Presentation, [Parameter(Mandatory)][string]$Path, [ValidateSet('Ansi','PlainText','Markdown','Html','Psd1','Json')][string]$Format = 'PlainText', [switch]$Force ) $targetPath = [System.IO.Path]::GetFullPath($Path, (Get-Location).Path) $exists = Test-Path -LiteralPath $targetPath -PathType Leaf if ($exists -and -not $Force) { throw "Path '$targetPath' already exists. Use -Force to overwrite it." } if (-not $PSCmdlet.ShouldProcess($targetPath, "Export presentation as $Format")) { return } $visiblePresentation = New-TerminalPresentationView -Presentation $Presentation $portableFormats = @('Markdown','Html','Psd1','Json') $portableExport = if ($Format -in $portableFormats) { New-TerminalPortableExport -Presentation $visiblePresentation -TargetPath $targetPath -Overwrite:$Force.IsPresent } else { [pscustomobject]@{ Presentation = $visiblePresentation; Transaction = $null } } $exportPresentation = $portableExport.Presentation $slides = @($exportPresentation.Slides) try { $content = switch ($Format) { 'Ansi' { $rendered = foreach ($slide in $slides) { Render-TerminalPresentationToString -Presentation $exportPresentation -SlideIndex ($slide.Index - 1) -RevealStep (Get-TerminalSlideMaximumRevealStep -Slide $slide) } $rendered -join ([Environment]::NewLine + [Environment]::NewLine + ('-' * 40) + [Environment]::NewLine) } 'PlainText' { $rendered = foreach ($slide in $slides) { Render-TerminalPresentationToString -Presentation $exportPresentation -SlideIndex ($slide.Index - 1) -RevealStep (Get-TerminalSlideMaximumRevealStep -Slide $slide) -PlainText } $rendered -join ("`n" + ('-' * 40) + "`n") } 'Markdown' { $visibleDocument = ConvertTo-TerminalMarkdownDocument $exportPresentation $presentationData = ConvertTo-PresentationData -Presentation $exportPresentation $marker = [ordered]@{ MarkerVersion = 2 ProjectionHash = Get-TerminalMarkdownProjectionHash -VisibleDocument $visibleDocument -PresentationData $presentationData Presentation = $presentationData } $visibleDocument + '<!-- terminalslides:envelope ' + (ConvertTo-TerminalDataMarker $marker) + ' -->' } 'Html' { $encode = { param($Value) ConvertTo-TerminalHtmlEncodedText -Value $Value } $style = ConvertTo-TerminalHtmlStyle (Resolve-TerminalPresentationTheme -Presentation $exportPresentation) $slidesHtml = foreach ($slide in $slides) { $body = foreach ($element in $slide.Elements) { ConvertTo-TerminalHtmlElement -Element $element } '<section class="slide"><h2>' + (& $encode $slide.Title) + '</h2>' + ($body -join '') + '</section>' } @" <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <title>$(& $encode $Presentation.Title)</title> <style> $style </style> </head> <body> <h1>$(& $encode $Presentation.Title)</h1> $($slidesHtml -join [Environment]::NewLine) </body> </html> "@ } 'Psd1' { $data = ConvertTo-PresentationData -Presentation $exportPresentation $marker = ConvertTo-TerminalDataMarker -Data $data "@{ TerminalSlidesEnvelope = '$marker' }" + [Environment]::NewLine } 'Json' { ConvertTo-TerminalWireJson (ConvertTo-PresentationData -Presentation $exportPresentation) } } Write-TerminalExportFile -Path $targetPath -Content ([string]$content) -Overwrite:$Force.IsPresent -MediaTransaction $portableExport.Transaction } finally { if ($portableExport.Transaction -and $portableExport.Transaction.StagingDirectory -and (Test-Path -LiteralPath $portableExport.Transaction.StagingDirectory)) { Remove-Item -LiteralPath $portableExport.Transaction.StagingDirectory -Recurse -Force -ErrorAction SilentlyContinue } if ($portableExport.Transaction) { Remove-TerminalCreatedDirectoriesIfEmpty ` -Paths ([string[]]@($portableExport.Transaction.CreatedTargetDirectories)) } } Get-Item -LiteralPath $targetPath } |