Powershell MultiColored текст в одну строку И по центру - PullRequest
1 голос
/ 03 апреля 2019

У меня есть функция powershell, которую нужно изменить.Функция центрирует текст в терминале, однако мне нужно иметь возможность выводить несколько цветов для текста в одной строке.Если я сделаю -NoNewLine и сделаю больше Write-host, чтобы изменить цвет ... тогда он все равно вычислит ширину терминала и добавит столько же отступов, сколько и без добавления -NoNewLine.По сути, я хочу, чтобы мой текст центрировался, и я хочу использовать несколько цветов.С тем, что у меня есть, я могу сделать только 1 цвет на линию.

function WriteCentered([String] $text, $color = $null)
{
    $width = [int](Get-Host).UI.RawUI.BufferSize.Width
    $twidth = [int]$text.Length
    $offset = ($width / 2) - ($twidth / 2)
    $newText = $text.PadLeft($offset + $twidth)

    if($color)
    {
        Write-Host $newText -ForegroundColor $color
    }        
    else
    {
        Write-Host $newText 
    }


}   

Я добавил больше условий IF, я изменил свои вычисления заполнения, у меня возникли проблемы с правильным выбором.

1 Ответ

1 голос
/ 06 апреля 2019

Модуль PowerShell PSWriteColor уже хорошо справляется с выводом нескольких цветов на одной строке.Либо вы загружаете его непосредственно из GitHub и импортируете его с помощью Import-Module <PATH-TO>\PSWriteColor.psd1, либо устанавливаете его непосредственно из галереи PowerShell с помощью Install-Module -Name PSWriteColor.

Краткий синтаксис: Write-Color -Text "GreenText","RedText","BlueText" -Color Green,Red,Blue.Поэтому нам нужно добавить аргумент [String[]]$Text строкой, содержащей необходимые пробелы, чтобы центрировать сообщение на экране и соответствующим образом добавить цвет к аргументу [ConsoleColor[]]$Color.

Вот небольшая вспомогательная функция дляcentering.

#Requires -Modules @{ ModuleName="PSWriteColor"; ModuleVersion="0.8.5" }
function WriteColor-Centered {
param(
    [Parameter(Mandatory=$true)][string[]]$Text,
    [Parameter(Mandatory=$true)][ConsoleColor[]]$Color
)
    $messageLength = 0
    $Text | ForEach-Object { $messageLength += $_.Length }

    [String[]] $centeredText = "{0}" -f (' ' * (([Math]::Max(0, $Host.UI.RawUI.BufferSize.Width / 2) - [Math]::Floor($messageLength / 2))))
    $centeredText += $Text

    [ConsoleColor[]]$OutColor = @([ConsoleColor]::White)
    $OutColor += $Color

    Write-Color -Text $centeredText -Color $OutColor
    # Alt.: use WriteColor-Core, see below
    # WriteColor-Core -Text $centeredText -Color $OutColor
}

Я скопировал вычисление пробелов из этого ответа stackoverflow .

EDIT: меня спрашивали, возможно ли сделать эту работу без импорта модуля,Честно говоря, сейчас я чувствую себя немного грязно, потому что я вошел в исходный код хорошо написанного модуля, убрал из него всю функциональность и обработку ошибок и вставил его сюда.

В любом случае - если вы замените вызов Write-Color в функции-обертке выше и вызовете следующее WriteColor-Core, вместо этого вы можете отказаться от загрузки модуля PSWriteColor.

function WriteColor-Core {
param(
    [Parameter(Mandatory=$true)][string[]]$Text,
    [Parameter(Mandatory=$true)][ConsoleColor[]]$Color
)
    # Fallback defaults if one of the values isn't set
    $LastForegroundColor = [console]::ForegroundColor
    # The real deal coloring
    for ($i = 0; $i -lt $Text.Count; $i++) {
        $CurrentFGColor = if ($Color[$i]) { $Color[$i] } else { $LastForegroundColor }
        $WriteParams = @{
            NoNewLine       = $true
            ForegroundColor = $CurrentFGColor
        }
        Write-Host $Text[$i] @WriteParams
        # Store last color set, in case next iteration doesn't have a set color
        $LastForegroundColor = $CurrentFGColor
    }

    Write-Host
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...