platyPS.psm1
# # # PPPPPPPPPPPPPPPPP lllllll tttt PPPPPPPPPPPPPPPPP SSSSSSSSSSSSSSS # P::::::::::::::::P l:::::l ttt:::t P::::::::::::::::P SS:::::::::::::::S # P::::::PPPPPP:::::P l:::::l t:::::t P::::::PPPPPP:::::P S:::::SSSSSS::::::S # PP:::::P P:::::Pl:::::l t:::::t PP:::::P P:::::PS:::::S SSSSSSS # P::::P P:::::P l::::l aaaaaaaaaaaaa ttttttt:::::tttttttyyyyyyy yyyyyyyP::::P P:::::PS:::::S # P::::P P:::::P l::::l a::::::::::::a t:::::::::::::::::t y:::::y y:::::y P::::P P:::::PS:::::S # P::::PPPPPP:::::P l::::l aaaaaaaaa:::::at:::::::::::::::::t y:::::y y:::::y P::::PPPPPP:::::P S::::SSSS # P:::::::::::::PP l::::l a::::atttttt:::::::tttttt y:::::y y:::::y P:::::::::::::PP SS::::::SSSSS # P::::PPPPPPPPP l::::l aaaaaaa:::::a t:::::t y:::::y y:::::y P::::PPPPPPPPP SSS::::::::SS # P::::P l::::l aa::::::::::::a t:::::t y:::::y y:::::y P::::P SSSSSS::::S # P::::P l::::l a::::aaaa::::::a t:::::t y:::::y:::::y P::::P S:::::S # P::::P l::::l a::::a a:::::a t:::::t tttttt y:::::::::y P::::P S:::::S # PP::::::PP l::::::la::::a a:::::a t::::::tttt:::::t y:::::::y PP::::::PP SSSSSSS S:::::S # P::::::::P l::::::la:::::aaaa::::::a tt::::::::::::::t y:::::y P::::::::P S::::::SSSSSS:::::S # P::::::::P l::::::l a::::::::::aa:::a tt:::::::::::tt y:::::y P::::::::P S:::::::::::::::SS # PPPPPPPPPP llllllll aaaaaaaaaa aaaa ttttttttttt y:::::y PPPPPPPPPP SSSSSSSSSSSSSSS # y:::::y # y:::::y # y:::::y # y:::::y # yyyyyyy # # .ExternalHelp platyPS.psm1-Help.xml function Get-PlatyPSMarkdown { [CmdletBinding()] [OutputType([string[]])] param( [Parameter(Mandatory=$true, ValueFromPipeline=$true, ParameterSetName="FromModule")] [object]$module, [Parameter(Mandatory=$true, ValueFromPipeline=$true, ParameterSetName="FromCommand")] [object]$command, [Parameter(Mandatory=$true, ValueFromPipeline=$true, ParameterSetName="FromMaml")] [string]$maml, [switch]$OneFilePerCommand, [string]$OutputFolder ) begin { if ($OneFilePerCommand) { if (-not $OutputFolder) { throw 'Specify -OutputFolder parameter, when you use -OneFilePerCommand' } else { mkdir $OutputFolder -ErrorAction SilentlyContinue > $null } } else { if ($OutputFolder) { Write-Warning "-OutputFolder $OutputFolder ignored. Use -OneFilePerCommand with it" } } } process { if ($PSCmdlet.ParameterSetName -eq 'FromMaml') { if (Test-Path $maml) { $maml = cat -raw $maml } if ($OneFilePerCommand) { Convert-MamlToMarkdown $maml -OutputFolder $OutputFolder } else { Convert-MamlToMarkdown $maml | Out-String } } elseif ($PSCmdlet.ParameterSetName -eq 'FromCommand') { $md = Convert-HelpToMarkdown (Get-Help $command) if ($OneFilePerCommand) { Out-MarkdownToFile -path (Join-Path $OutputFolder "$command.md") -value $md } else { $md } } else # "FromModule" { $commands = (get-module $module).ExportedCommands.Keys $commands | % { $command = $_ $h = Get-Help $module\$command $md = Convert-HelpToMarkdown $h if ($OneFilePerCommand) { Out-MarkdownToFile -path (Join-Path $OutputFolder "$command.md") -value $md } else { $md } } | Out-String } } } # .ExternalHelp platyPS.psm1-Help.xml function Get-PlatyPSExternalHelp { [CmdletBinding()] [OutputType([string])] param( [Parameter(Mandatory=$true, ParameterSetName="Strings")] [string[]]$markdown, [Parameter(Mandatory=$true, ParameterSetName="MarkdownFolder")] [string]$MarkdownFolder, [switch]$skipPreambula ) # normalize input if ($MarkdownFolder) { $markdown = ls $MarkdownFolder -File -Filter "*.md" | % { cat -Raw $_.FullName } } Add-Type -Path $PSScriptRoot\Markdown.MAML.dll $r = new-object -TypeName 'Markdown.MAML.Renderer.MamlRenderer' $p = new-object -TypeName 'Markdown.MAML.Parser.MarkdownParser' -ArgumentList { param([int]$current, [int]$all) Write-Progress -Activity "Parsing markdown" -status "Progress:" -percentcomplete ($current/$all*100) } $t = new-object -TypeName 'Markdown.MAML.Transformer.ModelTransformer' -ArgumentList { param([string]$message) Write-Verbose $message } $model = $p.ParseString($markdown) Write-Progress -Activity "Parsing markdown" -Completed $maml = $t.NodeModelToMamlModel($model) $xml = $r.MamlModelToString($maml, [bool]$skipPreambula) return $xml } # .ExternalHelp platyPS.psm1-Help.xml function New-PlatyPSModuleFromMaml { param ( [Parameter(Mandatory=$true)] [ValidateNotNullOrEmpty()] [String] $MamlFilePath, [ValidateNotNullOrEmpty()] [String] $DestinationPath = "$env:TEMP\Modules" ) if (-not (Test-Path $MamlFilePath)) { throw "'$MamlFilePath' does not exist." } # Get the file name $originalHelpFileName = (Get-Item $MamlFilePath).Name # Read the malm file $xml = [xml](Get-Content $MamlFilePath -Raw -ea SilentlyContinue) if (-not $xml) { throw "Failed to read '$MamlFilePath'" } # This logic is for the generate a module name $moduleType = $null if ($originalHelpFileName.EndsWith(".psm1-help.xml")) { $moduleType = ".psm1-help.xml" } elseif ($originalHelpFileName.EndsWith(".dll-help.xml")) { $moduleType = ".dll-help.xml" } else { throw "invalid PowerShell module help file $originalHelpFileName" } # The information for the module to be generated $currentCulture = (Get-UICulture).Name $moduleName = $originalHelpFileName.Replace($moduleType, "") + "_" + (Get-Random).ToString() $moduleFolder = "$destinationPath\$moduleName" $helpFileFolder = "$destinationPath\$moduleName\$currentCulture" $moduleFilePath = $moduleFolder + "\" + $moduleName + ".psm1" # The help file will be renamed to this name $helpFileNewName = $moduleName + $moduleType # The result object to be generated $result = @{ Name = $null Cmdlets = @() Path = $null } $writeFile = $false $moduleDefintion = "" $template = @' <# .ExternalHelp $helpFileName #> function $cmdletName { [CmdletBinding()] Param ( $Param1, $Param2 ) } '@ foreach ($command in $xml.helpItems.command.details) { $thisDefinition = $template $thisDefinition = $thisDefinition.Replace("`$helpFileName", $helpFileNewName) $thisDefinition = $thisDefinition.Replace("`$cmdletName", $command.name) $moduleDefintion += "`r`n" + $thisDefinition + "`r`n" $writeFile = $true $result.Cmdlets += $command.name } if (-not $writeFile) { Write-Verbose "There aren't any cmdlets definitions on '$MamlFilePath'." -Verbose return } # Create the module and help content folders. #New-Item -Path $moduleFolder -ItemType Directory -Force | Out-Null New-Item -Path $helpFileFolder -ItemType Directory -Force | Out-Null # Copy the help file Copy-Item -Path $MamlFilePath -Destination $helpFileFolder -Force # Rename the copied help file $filePath = Join-Path $helpFileFolder (Split-Path $MamlFilePath -Leaf) Rename-Item -Path $filePath -NewName $helpFileNewName -Force # Create the module file Set-Content -Value $moduleDefintion -Path $moduleFilePath $result.Name = $moduleName $result.Path = $moduleFilePath return $result } # # IIIIIIIIII lllllll tttt tttt iiii # I::::::::I l:::::l ttt:::t ttt:::t i::::i # I::::::::I l:::::l t:::::t t:::::t iiii # II::::::II l:::::l t:::::t t:::::t # I::::I mmmmmmm mmmmmmm ppppp ppppppppp l::::l eeeeeeeeeeee mmmmmmm mmmmmmm eeeeeeeeeeee nnnn nnnnnnnn ttttttt:::::ttttttt aaaaaaaaaaaaa ttttttt:::::ttttttt iiiiiii ooooooooooo nnnn nnnnnnnn # I::::I mm:::::::m m:::::::mm p::::ppp:::::::::p l::::l ee::::::::::::ee mm:::::::m m:::::::mm ee::::::::::::ee n:::nn::::::::nn t:::::::::::::::::t a::::::::::::a t:::::::::::::::::t i:::::i oo:::::::::::oo n:::nn::::::::nn # I::::I m::::::::::mm::::::::::mp:::::::::::::::::p l::::l e::::::eeeee:::::eem::::::::::mm::::::::::m e::::::eeeee:::::een::::::::::::::nn t:::::::::::::::::t aaaaaaaaa:::::at:::::::::::::::::t i::::i o:::::::::::::::on::::::::::::::nn # I::::I m::::::::::::::::::::::mpp::::::ppppp::::::p l::::l e::::::e e:::::em::::::::::::::::::::::me::::::e e:::::enn:::::::::::::::ntttttt:::::::tttttt a::::atttttt:::::::tttttt i::::i o:::::ooooo:::::onn:::::::::::::::n # I::::I m:::::mmm::::::mmm:::::m p:::::p p:::::p l::::l e:::::::eeeee::::::em:::::mmm::::::mmm:::::me:::::::eeeee::::::e n:::::nnnn:::::n t:::::t aaaaaaa:::::a t:::::t i::::i o::::o o::::o n:::::nnnn:::::n # I::::I m::::m m::::m m::::m p:::::p p:::::p l::::l e:::::::::::::::::e m::::m m::::m m::::me:::::::::::::::::e n::::n n::::n t:::::t aa::::::::::::a t:::::t i::::i o::::o o::::o n::::n n::::n # I::::I m::::m m::::m m::::m p:::::p p:::::p l::::l e::::::eeeeeeeeeee m::::m m::::m m::::me::::::eeeeeeeeeee n::::n n::::n t:::::t a::::aaaa::::::a t:::::t i::::i o::::o o::::o n::::n n::::n # I::::I m::::m m::::m m::::m p:::::p p::::::p l::::l e:::::::e m::::m m::::m m::::me:::::::e n::::n n::::n t:::::t tttttta::::a a:::::a t:::::t tttttt i::::i o::::o o::::o n::::n n::::n # II::::::IIm::::m m::::m m::::m p:::::ppppp:::::::pl::::::le::::::::e m::::m m::::m m::::me::::::::e n::::n n::::n t::::::tttt:::::ta::::a a:::::a t::::::tttt:::::ti::::::io:::::ooooo:::::o n::::n n::::n # I::::::::Im::::m m::::m m::::m p::::::::::::::::p l::::::l e::::::::eeeeeeee m::::m m::::m m::::m e::::::::eeeeeeee n::::n n::::n tt::::::::::::::ta:::::aaaa::::::a tt::::::::::::::ti::::::io:::::::::::::::o n::::n n::::n # I::::::::Im::::m m::::m m::::m p::::::::::::::pp l::::::l ee:::::::::::::e m::::m m::::m m::::m ee:::::::::::::e n::::n n::::n tt:::::::::::tt a::::::::::aa:::a tt:::::::::::tti::::::i oo:::::::::::oo n::::n n::::n # IIIIIIIIIImmmmmm mmmmmm mmmmmm p::::::pppppppp llllllll eeeeeeeeeeeeee mmmmmm mmmmmm mmmmmm eeeeeeeeeeeeee nnnnnn nnnnnn ttttttttttt aaaaaaaaaa aaaa ttttttttttt iiiiiiii ooooooooooo nnnnnn nnnnnn # p:::::p # p:::::p # p:::::::p # p:::::::p # p:::::::p # ppppppppp function Convert-MamlLinksToMarkDownLinks { [CmdletBinding()] param( [Parameter(Mandatory=$false, ValueFromPipeline=$true)] $maml ) process { function Convert([string]$s) { ($s -replace "`n", '') -replace '<maml:navigationLink(.*?)><maml:linkText>(.*?)</maml:linkText><maml:uri>(.*?)</maml:uri></maml:navigationLink>', '[$2]($3)' } if (-not $maml) { return $maml } if ($maml -is [System.Xml.XmlElement]) { return ([xml](Convert (Convert-XmlElementToString $maml))).para.'#text' } if ($maml -is [string]) { return $maml } $maml '' # new line for <para> } } function Get-EscapedMarkdownText { [CmdletBinding()] param( [Parameter(Mandatory=$false, ValueFromPipeline=$true)] [string]$text ) process { # this is kind of a crazy replacement to handle escaping properly. # we need to do the reverse operation in our markdown parser. # the last part is to make generated markdown more readable. (((($text -replace '\\\\','\\\\') -replace '([<>])','\$1') -replace '\\([\[\]\(\)])', '\\$1') -replace "\.( )+(\w)", ".`r`n`$2").Trim() } } function Add-LineBreaksForParagraphs { [CmdletBinding()] param( [Parameter(Mandatory=$false, ValueFromPipeline=$true)] [string]$text ) begin { $first = $true } process { if (-not $text) { return $text } if ($first) { $first = $false } else { "" } $text } } function Get-NameMarkdown($command) { if ($script:IS_HELP) { $name = $command.Name } else { $name = $command.details.name.Trim() } "# {0}" -f $name } function Get-SynopsisMarkdown($command) { '## SYNOPSIS' if ($script:IS_HELP) { $text = $command.Synopsis } else { $text = $command.details.description.para | Convert-MamlLinksToMarkDownLinks } $text | Get-EscapedMarkdownText | Add-LineBreaksForParagraphs } function Get-DescriptionMarkdown($command) { '## DESCRIPTION' if ($script:IS_HELP) { $text = $command.description } else { $text = $command.description.para | Convert-MamlLinksToMarkDownLinks } $text | Get-EscapedMarkdownText | Add-LineBreaksForParagraphs } <# .EXAMPLE 'SwitchParameter' -> [switch] 'System.Int32' -> [int] # optional #> function Convert-ParameterTypeTextToType { [CmdletBinding()] param( [Parameter(Mandatory=$true, ValueFromPipeline=$true)] $parameter ) if ($script:IS_HELP) { $typeText = $parameter.type.name } else { $typeText = $parameter.parameterValue.'#text' } # if type is explicitly [object], we want to capture it # if type is not specified, then we don't want to capture it if (-not $typeText) { # return nothing return '' } if ($typeText -eq 'SwitchParameter') { return '[switch]' } # default return "[$typeText]" } function Get-ParamMetadata { param( [Parameter(Mandatory=$true)] $parameter, [Parameter(Mandatory=$false)] $paramSet ) $ValidateSetGenerated = $false foreach ($setPair in $paramSet.GetEnumerator()) { $paramSetName = $setPair.Key $syntaxParam = $setPair.Value $meta = @() if ($syntaxParam.required -eq 'true') { $meta += 'Mandatory = $true' } if ($syntaxParam.position -ne 'named') { $meta += 'Position = ' + ($syntaxParam.position) } if ($syntaxParam.pipelineInput -eq 'True (ByValue)') { $meta += 'ValueFromPipeline = $true' } elseif ($syntaxParam.pipelineInput -eq 'True (ByPropertyName)') { $meta += 'ValueFromPipelineByPropertyName = $true' } elseif ($syntaxParam.pipelineInput -eq 'True (ByPropertyName, ByValue)') { # mind the order $meta += 'ValueFromPipelineByPropertyName = $true' $meta += 'ValueFromPipeline = $true' } elseif ($syntaxParam.pipelineInput -eq 'true (ByValue, ByPropertyName)') { # mind the order $meta += 'ValueFromPipeline = $true' $meta += 'ValueFromPipelineByPropertyName = $true' } if ($paramSetName -ne '*') { $meta += "ParameterSetName = '$paramSetName'" } if ($meta) { # formatting hustle if ($meta.Count -eq 1) { "[Parameter($meta)]" } else { "[Parameter(`n " + ($meta -join ",`n ") + ")]" } } if (-not $ValidateSetGenerated) { # [ValidateSet()] is a separate attribute from [Parameter()]. # That means, we cannot specify ValidateSet per parameterSet. $validateSet = $syntaxParam.parameterValueGroup.parameterValue.'#text' if ($validateSet) { "[ValidateSet(`n '" + ($validateSet -join "',`n '") + "')]" $ValidateSetGenerated = $true } } } } function Get-ParameterMarkdown { param( [Parameter(Mandatory=$true)] $parameter, [Parameter(Mandatory=$true)] [hashtable]$paramSets ) #if (@('InformationAction', 'InformationVariable') -contains $parameter.name) #{ # ignoring common parameters # return #} $parameterType = Convert-ParameterTypeTextToType $parameter $defaultValue = '' if ($parameter.defaultValue -and $parameter.defaultValue -ne 'none' -and ($parameterType -ne '[switch]' -or $parameter.defaultValue -ne 'false')) { $defaultValue = " = $($parameter.defaultValue)" } @" ### $($parameter.name) $parameterType$defaultValue "@ $parameterMetadata = Get-ParamMetadata $parameter -paramSet ($paramSets[$parameter.name]) | Out-String if ($parameter.globbing -eq 'true') { $parameterMetadata += "[SupportsWildCards()]`n" } if ($parameterMetadata) { @" ``````powershell $parameterMetadata`````` "@ } $parameter.description.para | Convert-MamlLinksToMarkDownLinks | Get-EscapedMarkdownText | Add-LineBreaksForParagraphs $parameter.parameters.parameter | Convert-MamlLinksToMarkDownLinks | Get-EscapedMarkdownText } <# .SYNOPSIS Get map 'parameterName' -> ('setName' -> parameterXml) 'Parameter sets that it belongs to -> '. '*' for setName mean it belongs to default set. Note: for some magical reason this logic works for both Maml xml and Help parameters object. #> function Get-ParameterSetMapping($command) { function Simplify($set) { foreach ($i in 1..($set.Count-1)) { if (($set[0].required -ne $set[$i].required) -or ($set[0].pipelineInput -ne $set[$i].pipelineInput) -or ($set[0].position -ne $set[$i].position) -or ($set[0].variableLength -ne $set[$i].variableLength)) { return $set } } return [ordered]@{'*' = $set[0]} } $syntax = $command.syntax $result = @{} $collection = $syntax.syntaxItem # If syntax entries are not properly filled up, # we are assuming that there is only one parameterSet # and take all values for it from parameters section. if (-not $collection.parameter) { $collection = $command.parameters } if (-not $collection.parameter) { Write-Warning ("No syntax and no parameters entries are found for command " + $command.details.name.Trim()) return $result } try { $i = 0 $collection | % { $i++ $paramSetName = "Set $i" $_.parameter | % { $p = $_ if ($result[$p.name]) { $result[$p.name][$paramSetName] = $p } else { $result[$p.name] = [ordered]@{$paramSetName = $p} } } } # at this point, if parameter belongs to all parameter sets, # we should try to remove any notation for parameter sets, if metadata is the same for all of them. @($result.Keys) | % { if ($i -eq ($result[$_].Count)) { $result[$_] = Simplify $result[$_] } } } catch { Write-Warning ("Error processing syntax entries for " + $command.details.name.Trim()) Write-Error $_ } return $result } function Get-ParametersMarkdown($command) { $paramSets = Get-ParameterSetMapping $command '## PARAMETERS' '' $command.parameters.parameter | % { # can be null, if parameters are not populated if ($_) { Get-ParameterMarkdown $_ -paramSets $paramSets '' } } } function Get-InputMarkdown($command) { '## INPUTS' if ($command.inputTypes.inputType.type.name) { # there is a weired difference for some reason if ($script:IS_HELP) { $command.inputTypes.inputType.type.name.Split() | ? {$_} | % { "### $($_)" } } else { $command.inputTypes.inputType | % { "### $($_.type.name)" $_.type.description.para | Convert-MamlLinksToMarkDownLinks | Get-EscapedMarkdownText | Add-LineBreaksForParagraphs $_.description.para | Convert-MamlLinksToMarkDownLinks | Get-EscapedMarkdownText | Add-LineBreaksForParagraphs } } } else { "### None" $command.inputTypes.inputType.type.description.para | Convert-MamlLinksToMarkDownLinks | Get-EscapedMarkdownText | Add-LineBreaksForParagraphs } } function Get-OutputMarkdown($command) { '## OUTPUTS' if ($command.returnValues.returnValue) { if ($script:IS_HELP) { # didn't test it, but I guess it should be the same as Inputs $command.returnValues.returnValue.type.name.Split() | ? {$_} | % { "### $($_)" } } else { $command.returnValues.returnValue | % { "### $($_.type.name)" $_.type.description.para | Convert-MamlLinksToMarkDownLinks | Get-EscapedMarkdownText | Add-LineBreaksForParagraphs $_.description.para | Convert-MamlLinksToMarkDownLinks | Get-EscapedMarkdownText | Add-LineBreaksForParagraphs } } } else { "### None" $command.returnValues.returnValue.type.description.para | Convert-MamlLinksToMarkDownLinks | Get-EscapedMarkdownText | Add-LineBreaksForParagraphs } } function Get-NotesMarkdown($command) { if ($command.alertSet.alert.para -or $script:IS_HELP) { '## NOTES' $command.alertSet.alert.para | Convert-MamlLinksToMarkDownLinks | Get-EscapedMarkdownText | Add-LineBreaksForParagraphs } } function Get-ExampleMarkdown($example) { if ($example.title) { "### $($example.title.Trim())" } else { "### EXAMPLE" } $example.introduction.para | Convert-MamlLinksToMarkDownLinks | Get-EscapedMarkdownText | Add-LineBreaksForParagraphs '```powershell' $example.code '```' $example.remarks.para | Convert-MamlLinksToMarkDownLinks | Get-EscapedMarkdownText | Add-LineBreaksForParagraphs } function Get-ExamplesMarkdown($command) { if ($command.examples.example -or $script:IS_HELP) { '## EXAMPLES' $command.examples.example | ? {$_} | % { Get-ExampleMarkdown $_ } } } function Get-RelatedLinksMarkdown($command) { '## RELATED LINKS' $command.relatedLinks.navigationLink | ? {$_} | % { "`n[$($_.linkText)]($($_.uri))" } } function Convert-CommandToMarkdown { [CmdletBinding()] param( [Parameter(Mandatory=$true, ValueFromPipeline=$true, ParameterSetName="Maml")] [System.Xml.XmlElement]$command, [Parameter(Mandatory=$true, ValueFromPipeline=$true, ParameterSetName="HelpObject")] $HelpObject, [Parameter(ParameterSetName="HelpObject")] [switch]$IsHelpObject ) if ($IsHelpObject) { $o = $helpObject $script:IS_HELP = $true } else { $o = $command } Get-NameMarkdown $o '' Get-SynopsisMarkdown $o '' Get-DescriptionMarkdown $o '' Get-ParametersMarkdown $o '' Get-InputMarkdown $o '' Get-OutputMarkdown $o '' Get-NotesMarkdown $o '' Get-ExamplesMarkdown $o '' Get-RelatedLinksMarkdown $o '' if ($IsHelpObject) { $script:IS_HELP = $false } } function Convert-XmlElementToString { [CmdletBinding()] param( [Parameter(Mandatory=$true, ValueFromPipeline=$true)] $xml ) process { $sw = New-Object System.IO.StringWriter $xmlSettings = New-Object System.Xml.XmlWriterSettings $xmlSettings.ConformanceLevel = [System.Xml.ConformanceLevel]::Fragment $xmlSettings.Indent = $true $xw = [System.Xml.XmlWriter]::Create($sw, $xmlSettings) $xml.WriteTo($xw) $xw.Close() # return $sw.ToString() } } function Get-NormalizedText([string]$text) { # just normize some commmon typos $text -replace '–','-' } function Out-MarkdownToFile { param( [string]$Path, [string]$value ) Write-Host "Writing to $Path" Set-Content -Path $Path -Value $md -Encoding UTF8 } function Convert-MamlToMarkdown { [CmdletBinding()] param( [Parameter(Mandatory=$true)] [string]$maml, [string]$OutputFolder ) $xmlMaml = [xml](Get-NormalizedText $maml) $commands = $xmlMaml.helpItems.command $commands | %{ if ($OutputFolder) { $md = Convert-CommandToMarkdown -command $_ $fileName = "$($_.details.name.Trim()).md" Out-MarkdownToFile -path (Join-Path $OutputFolder $fileName) -value $md } else { Convert-CommandToMarkdown -command $_ } } | Out-String } function Convert-HelpToMarkdown { [CmdletBinding()] param( [Parameter(Mandatory=$true)] $helpObject ) Convert-CommandToMarkdown -helpObject $helpObject -IsHelpObject | Out-String } # # EEEEEEEEEEEEEEEEEEEEEE tttt # E::::::::::::::::::::E ttt:::t # E::::::::::::::::::::E t:::::t # EE::::::EEEEEEEEE::::E t:::::t # E:::::E EEEEEExxxxxxx xxxxxxxppppp ppppppppp ooooooooooo rrrrr rrrrrrrrr ttttttt:::::ttttttt # E:::::E x:::::x x:::::x p::::ppp:::::::::p oo:::::::::::oo r::::rrr:::::::::r t:::::::::::::::::t # E::::::EEEEEEEEEE x:::::x x:::::x p:::::::::::::::::p o:::::::::::::::or:::::::::::::::::r t:::::::::::::::::t # E:::::::::::::::E x:::::xx:::::x pp::::::ppppp::::::po:::::ooooo:::::orr::::::rrrrr::::::rtttttt:::::::tttttt # E:::::::::::::::E x::::::::::x p:::::p p:::::po::::o o::::o r:::::r r:::::r t:::::t # E::::::EEEEEEEEEE x::::::::x p:::::p p:::::po::::o o::::o r:::::r rrrrrrr t:::::t # E:::::E x::::::::x p:::::p p:::::po::::o o::::o r:::::r t:::::t # E:::::E EEEEEE x::::::::::x p:::::p p::::::po::::o o::::o r:::::r t:::::t tttttt # EE::::::EEEEEEEE:::::E x:::::xx:::::x p:::::ppppp:::::::po:::::ooooo:::::o r:::::r t::::::tttt:::::t # E::::::::::::::::::::E x:::::x x:::::x p::::::::::::::::p o:::::::::::::::o r:::::r tt::::::::::::::t # E::::::::::::::::::::E x:::::x x:::::x p::::::::::::::pp oo:::::::::::oo r:::::r tt:::::::::::tt # EEEEEEEEEEEEEEEEEEEEEExxxxxxx xxxxxxx p::::::pppppppp ooooooooooo rrrrrrr ttttttttttt # p:::::p # p:::::p # p:::::::p # p:::::::p # p:::::::p # ppppppppp if ($env:PESTER_EXPORT_ALL_MEMBERS) { Export-ModuleMember -Function * } else { Export-ModuleMember -Function @('Get-PlatyPSMarkdown', 'Get-PlatyPSExternalHelp', 'New-PlatyPSModuleFromMaml') } |