utils.ps1
|
function ConvertFrom-AnsiEscapedString { [CmdletBinding()] param( [Parameter(ValueFromPipeline=$true, Position=0)] [string]$InputValObject ) begin { $escChar = [char]27 function Convert-Escapes { param([string]$s) if ($null -eq $s) { return $s } # Protect fenced triple-backtick blocks first $literals = New-Object System.Collections.Generic.List[string] $tokenIndex = 0 # newlines and returns $s = $s -replace '(?<!\\)\\n', "`n" $s = $s -replace '(?<!\\)\\r', "`r" # new lines are messed up # # Protect ```...``` (multiline, non-greedy) # $s = [Regex]::Replace($s, '```([\s\S]*?)```', { # param($m) # $literals.Add($m.Value) # store the whole fenced block including backticks # $token = "___ANSI_LITERAL_{0}___" -f $tokenIndex # $tokenIndex++ # return $token # }) # Then protect single-backtick inline spans `...` (no newlines) $s = [Regex]::Replace($s, '`([^`\r\n]*)`', { param($m) $literals.Add($m.Value) # store with backticks $token = "___ANSI_LITERAL_{0}___" -f $tokenIndex $tokenIndex++ return $token }) # \x5c033 -> ESC $s = $s -replace '\\x5c0*33', $escChar # common escape forms $s = $s -replace '\\033', $escChar $s = $s -replace '\\e', $escChar $s = $s -replace '\\x1b', $escChar $s = $s -replace '\\x1B', $escChar # replace generic \xHH sequences safely while ($s -match '\\x([0-9A-Fa-f]{2})') { $hex = $matches[1] $char = [char]([Convert]::ToInt32($hex,16)) $s = [Regex]::Replace($s, "\\x$hex", [Regex]::Escape($char), 1) $s = $s -replace [Regex]::Escape($char), $char } # Restore literal spans (tokens replaced with original stored values) for ($i = 0; $i -lt $literals.Count; $i++) { $token = "___ANSI_LITERAL_{0}___" -f $i $orig = $literals[$i] # Use Regex::Replace with escaped token -> escaped original, then unescape inserted original $s = [Regex]::Replace($s, [Regex]::Escape($token), [Regex]::Escape($orig)) $s = $s -replace [Regex]::Escape($orig), $orig } return $s } $collected = "" } process { $inputVal = $InputValObject if ($inputVal -is [System.Array]) { $inputVal = ($inputVal -join "`n") } elseif ($null -ne $inputVal -and $inputVal -isnot [string]) { $inputVal = $inputVal.ToString() } $out = Convert-Escapes -s $inputVal # if ($null -ne $out) { # Write-Host $out -noNewline # if ($out -match "(`r`n|`n)$") { Write-Host "" } # } $collected += $out } end { return $collected } } |