public/Export-HtmlCommandHelp.ps1
|
function Export-HtmlCommandHelp { <# .SYNOPSIS Custom HTML renderer for PlatyPS CommandHelp objects. .DESCRIPTION Demonstrates how to build a custom renderer using the PlatyPS v1 object model. PlatyPS ships built-in renderers for Markdown, YAML, and MAML. This script shows how to consume CommandHelp objects straight off the pipeline and emit any arbitrary output format – in this case self-contained HTML files that match what Get-Help would display, but in a browser-friendly layout. Pipeline pattern (mirrors the built-in Export-* cmdlets): # From live reflection New-CommandHelp -CommandInfo (Get-Command -Module MyModule) | Export-HtmlCommandHelp -OutputFolder .\html # From existing Markdown Measure-PlatyPSMarkdown -Path .\docs\*.md | Where-Object Filetype -match 'CommandHelp' | Import-MarkdownCommandHelp -Path { $_.FilePath } | Export-HtmlCommandHelp -OutputFolder .\html .PARAMETER CommandHelp One or more Microsoft.PowerShell.PlatyPS.Model.CommandHelp objects. Accepts pipeline input. .PARAMETER OutputFolder Root folder for the HTML files. A sub-folder named after the module is created automatically, mirroring the convention used by Export-MarkdownCommandHelp. .PARAMETER ThemeFile Path to a .psd1 theme file. Any keys present in the file override the built-in defaults; missing keys keep their default values. Copy themes\Default.psd1 from the module directory to get started. .PARAMETER Force Overwrite existing files without prompting. .PARAMETER PassThru Emit the generated FileInfo objects to the pipeline. .EXAMPLE Get-Command -Module Microsoft.PowerShell.Utility | Select-Object -First 5 | New-CommandHelp | .\Export-HtmlCommandHelp.ps1 -OutputFolder .\html -Force .EXAMPLE Import-MarkdownCommandHelp -Path .\docs\MyModule\Get-Widget.md | .\Export-HtmlCommandHelp.ps1 -OutputFolder .\html -PassThru #> [CmdletBinding(HelpUri = 'https://steviecoaster.github.io/PlatyPS.Hosting/PlatyPS.Hosting/Export-HtmlCommandHelp/',SupportsShouldProcess)] param( [Parameter(Mandatory, ValueFromPipeline)] [Microsoft.PowerShell.PlatyPS.Model.CommandHelp[]] $CommandHelp, [Parameter(Mandatory, Position = 0)] [string] $OutputFolder, [switch] $Force, [switch] $PassThru, [Parameter()] [string] $ThemeFile ) begin { $resolvedOutput = $PSCmdlet.SessionState.Path.GetUnresolvedProviderPathFromPSPath($OutputFolder) $theme = Resolve-HtmlTheme -ThemeFile $ThemeFile # Accumulate commands per module so we can build an index.html in end {} $commandsByModule = [System.Collections.Generic.Dictionary[string, System.Collections.Generic.List[Microsoft.PowerShell.PlatyPS.Model.CommandHelp]]]::new() } process { # Only accumulate - generation happens in end{} so every page # has the full command list available for sidebar navigation. foreach ($ch in $CommandHelp) { if (-not $commandsByModule.ContainsKey($ch.ModuleName)) { $commandsByModule[$ch.ModuleName] = [System.Collections.Generic.List[Microsoft.PowerShell.PlatyPS.Model.CommandHelp]]::new() } $commandsByModule[$ch.ModuleName].Add($ch) } } end { foreach ($moduleName in $commandsByModule.Keys) { $moduleFolder = Join-Path $resolvedOutput ($moduleName -replace '[^\w\-.]', '_') if (-not (Test-Path $moduleFolder)) { if ($PSCmdlet.ShouldProcess($moduleFolder, 'Create directory')) { $null = New-Item -ItemType Directory -Path $moduleFolder -Force } } $commands = $commandsByModule[$moduleName].ToArray() $sortedNames = $commands | Sort-Object Title | ForEach-Object { $_.Title } # ── Command pages ──────────────────────────────────────────────────── foreach ($ch in $commands) { $filePath = Join-Path $moduleFolder "$($ch.Title).html" if ((Test-Path $filePath) -and -not $Force) { Write-Warning "File already exists (use -Force to overwrite): $filePath" continue } if ($PSCmdlet.ShouldProcess($filePath, 'Write HTML help file')) { $html = New-HelpPage -Help $ch -AllCommands $sortedNames -Theme $theme [System.IO.File]::WriteAllText($filePath, $html, [System.Text.Encoding]::UTF8) Write-Verbose "Written: $filePath" if ($PassThru) { Get-Item -LiteralPath $filePath } } } # ── Index page ─────────────────────────────────────────────────────── $indexPath = Join-Path $moduleFolder 'index.html' if ((Test-Path $indexPath) -and -not $Force) { Write-Warning "Index already exists (use -Force to overwrite): $indexPath" continue } if ($PSCmdlet.ShouldProcess($indexPath, 'Write module index page')) { $indexHtml = New-ModuleIndexPage -ModuleName $moduleName -Commands $commands -Theme $theme [System.IO.File]::WriteAllText($indexPath, $indexHtml, [System.Text.Encoding]::UTF8) Write-Verbose "Written index: $indexPath" if ($PassThru) { Get-Item -LiteralPath $indexPath } } } } } |