Многоцветный текст Powershell в одной строке И по центру

У меня есть функция 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 
    }


}   

Я добавил больше условий ЕСЛИ, я изменил свои вычисления заполнения, у меня возникли проблемы с тем, чтобы сделать это правильно.

Вам нужно будет передать несколько строк и параллельный массив цветов, если вы хотите, чтобы несколько цветов отображались в одной строке, а составная строка находилась в центре.

mklement0 03.04.2019 21:33

Это не совсем то, что вам нужно, но его можно адаптировать: stackoverflow.com/a/46046113/45375 использует инструкции по раскрашиванию, встроенные в одну строку.

mklement0 03.04.2019 21:34
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
2
885
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

PowerShell-Module 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.

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

#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.

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

В любом случае, если вы замените вызов 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
}

Есть ли способ заставить это работать без модуля? Я надеялся заставить этот скрипт работать прямо из коробки.

shadow2020 06.04.2019 00:28

Я скопировал код из PSWriteColor. Теперь он должен работать без модуля.

boris 06.04.2019 07:35

Другие вопросы по теме