private/uitool/ConvertFrom-UiHelpMarkdown.ps1

function ConvertFrom-UiHelpMarkdown {
    <#
    .SYNOPSIS
        Takes the markdown out of Get-Help text so it reads as plain text on the form.
    #>

    [CmdletBinding()]
    param(
        [AllowNull()]
        [AllowEmptyCollection()]
        [string[]]$Text,

        # For captions. One line, with the emphasis and code bits removed since a caption is a plain TextBlock.
        [switch]$Inline,

        # For the Help button's console text, paragraphs kept, markup gone
        [switch]$Plain
    )

    $bullet     = [string][char]0x2022
    $paragraphs = [System.Collections.Generic.List[string]]::new()

    foreach ($chunk in $Text) {
        if ([string]::IsNullOrWhiteSpace($chunk)) { continue }

        foreach ($block in [regex]::Split($chunk.Replace("`r", ''), '\n[ \t]*\n')) {
            $lines = [System.Collections.Generic.List[string]]::new()
            foreach ($line in $block.Split("`n")) {
                $line = $line.Trim()
                if ($line) { $lines.Add($line) }
            }
            if ($lines.Count -eq 0) { continue }

            if ($lines[0].StartsWith('>')) {
                for ($i = 0; $i -lt $lines.Count; $i++) { $lines[$i] = $lines[$i] -replace '^>\s?', '' }

                # Get-Help joins wrapped lines with a space, leaving markers mid line
                if ($lines.Count -eq 1) { $lines[0] = $lines[0] -replace '\s>(?=\s|$)', '' }
            }

            # Get-Help's join flattens lists onto one line too.
            if ($lines.Count -eq 1) {
                if ($lines[0] -match '^-\s') { $lines = [regex]::Split($lines[0], '\s+(?=-\s)') }
                elseif ($lines[0] -match '^\d{1,3}[.)]\s') {
                    $lines = [regex]::Split($lines[0], '\s+(?=\d{1,3}[.)]\s)')
                }
            }

            $lead  = [System.Collections.Generic.List[string]]::new()
            $items = [System.Collections.Generic.List[string]]::new()
            foreach ($line in $lines) {
                $line = ($line -replace '\[!(NOTE|TIP|IMPORTANT|WARNING|CAUTION)\]', '').Trim()
                if (!$line) { continue }

                if ($line -match '^(?:[-*+]|(\d{1,3}[.)]))\s+(.+)$') {
                    $marker = if ($Matches[1]) { $Matches[1] } else { $bullet }
                    $items.Add("$marker $($Matches[2])")
                }
                elseif ($items.Count -gt 0) { $items[$items.Count - 1] += " $line" }
                else { $lead.Add($line) }
            }

            $parts = [System.Collections.Generic.List[string]]::new()
            if ($lead.Count -gt 0) { $parts.Add($lead -join ' ') }
            $parts.AddRange($items)
            if ($parts.Count -gt 0) { $paragraphs.Add($parts -join $(if ($Inline) { ' ' } else { "`n" })) }
        }
    }

    if ($Inline) {
        # Joined onto one line, a list or code sample without a full stop runs straight into the next paragraph
        for ($i = 0; $i -lt $paragraphs.Count - 1; $i++) {
            if ($paragraphs[$i] -notmatch '[.!?:;]\W*$') { $paragraphs[$i] += '.' }
        }
    }
    $result = $paragraphs -join $(if ($Inline) { ' ' } else { "`n`n" })

    # Links keep their text and drop the target which is a relative docs path or an xref that only resolves on the docs site
    $result = $result -replace '!?\[([^\]]*)\]\((?:[^()]|\([^()]*\))*\)', '$1'
    $result = $result -replace '\[([^\]]+)\]\[[^\]]*\]', '$1'
    $result = $result -replace '<(https?://[^>\s]+)>', '$1'

    if ($Inline -or $Plain) {
        # Emphasis only comes off outside code spans
        $pieces = foreach ($piece in [regex]::Split($result, '(`[^`\n]+`)')) {
            if ($piece.Length -gt 1 -and $piece.StartsWith('`') -and $piece.EndsWith('`')) {
                $piece.Substring(1, $piece.Length - 2)
            }
            else {
                $piece = $piece -replace '\*\*(.+?)\*\*', '$1'
                $piece -replace '(?<![\w*])\*(?![\s*])(.+?)(?<![\s*])\*(?![\w*])', '$1'
            }
        }
        $result = -join $pieces
    }
    $result = if ($Inline) { $result -replace '\s+', ' ' } else { $result -replace '[ \t]+', ' ' }

    $result.Trim()
}