src/WriteI18n.ps1
|
# Unified i18n for ps12exe and exe21sp. # - Set-I18nData: sets the lookup table for Write-I18n (call after loading locale). # - Write-I18n: pipeline output by key; Write-I18n Host|Error|Warning|... Mid [FormatArgs] [...] # - Write-SymboledI18n: symbol + message by key; Write-SymboledI18n Symbol MessageKey [SequenceKey] [-MessageFormatArgs] [-SymbolColor] [...] # Semantic wrappers: generated from $script:SymboledI18nWrapperDefs (table-driven, see below). $script:I18nData = $null function Set-I18nData { [CmdletBinding()] param( [Parameter(Mandatory = $true)] [hashtable]$I18nData ) $script:I18nData = $I18nData } function Write-I18n { [CmdletBinding()] param( [Parameter(Position = 0, Mandatory = $true)] [ValidateSet('Info', 'Warning', 'Error', 'Debug', 'Verbose', 'Host', 'Output')] [string]$PipeLineType, [Parameter(Position = 1, Mandatory = $true)] [string]$Mid, [Parameter(Position = 2)] [object[]]$FormatArgs, [string]$ErrorId, [System.Management.Automation.ErrorCategory]$Category = 'NotSpecified', $TargetObject, [System.Exception]$Exception, [ConsoleColor]$ForegroundColor = $Host.UI.RawUI.ForegroundColor ) $formatForF = if ($null -eq $FormatArgs) { @() } else { @($FormatArgs) } $template = if ($null -ne $script:I18nData -and $script:I18nData.ContainsKey($Mid)) { $script:I18nData[$Mid] } else { "fatal error: No i18n data for $Mid, Rest format args: $($formatForF -join ', ')" } $value = if ($formatForF.Count -gt 0) { $template -f $formatForF } else { $template } if (-not $ForegroundColor) { $ForegroundColor = 'White' } switch ($PipeLineType) { 'Info' { Write-Information $value } 'Warning' { Write-Warning $value } 'Error' { $errId = if ($PSBoundParameters.ContainsKey('ErrorId')) { $ErrorId } else { $Mid } if (-not $Exception) { $Exception = [System.Exception]::new($value) } try { $Host.UI.RawUI.ForegroundColor = 'Red' } catch {} $Host.UI.WriteErrorLine($value) try { $Host.UI.RawUI.ForegroundColor = $ForegroundColor } catch {} Write-Error -Exception $Exception -Message $value -Category $Category -ErrorId $errId -TargetObject $TargetObject -ErrorAction SilentlyContinue } 'Debug' { Write-Debug $value } 'Host' { Write-Host $value -ForegroundColor $ForegroundColor } 'Output' { $value } 'Verbose' { Write-Verbose $value } } } function Write-SymboledI18n { [CmdletBinding()] param( [Parameter(Position = 0, Mandatory = $true)] [string]$Symbol, [Parameter(Position = 1, Mandatory = $true)] [string]$MessageKey, [Parameter(Position = 2)] [string]$SequenceKey, [Parameter(Position = 3)] [object[]]$MessageFormatArgs, [ConsoleColor]$SymbolColor, [ConsoleColor]$MessageColor = 'White', [ConsoleColor]$SequenceColor = 'White' ) $msgTemplate = if ($null -ne $script:I18nData -and $script:I18nData.ContainsKey($MessageKey)) { $script:I18nData[$MessageKey] } else { "?$MessageKey?" } $message = if ($null -ne $MessageFormatArgs -and $MessageFormatArgs.Count -gt 0) { $msgTemplate -f @($MessageFormatArgs) } else { $msgTemplate } $sequence = if ($SequenceKey -and $null -ne $script:I18nData -and $script:I18nData.ContainsKey($SequenceKey)) { $script:I18nData[$SequenceKey] } else { '' } Write-Host -NoNewline " " Write-Host -ForegroundColor $SymbolColor $Symbol -NoNewline Write-Host -ForegroundColor $MessageColor " $message" -NoNewline Write-Host -ForegroundColor $SequenceColor " $sequence" } # Table: Name, Symbol, SymbolColor, MessageColor, SequenceColor. Wrappers are generated from this (single body, no duplication). $script:SymboledI18nWrapperDefs = @( @{ Name = 'Write-SymboledErrorI18n'; Symbol = '[!]'; SymbolColor = 'Red'; MessageColor = 'White'; SequenceColor = 'White' }, @{ Name = 'Write-SymboledQuestionI18n'; Symbol = '[?]'; SymbolColor = 'Blue'; MessageColor = 'White'; SequenceColor = 'DarkGray' }, @{ Name = 'Write-SymboledInfoI18n'; Symbol = '[*]'; SymbolColor = 'Green'; MessageColor = 'White'; SequenceColor = 'White' }, @{ Name = 'Write-SymboledWelcomeI18n'; Symbol = '[*]'; SymbolColor = 'Cyan'; MessageColor = 'White'; SequenceColor = 'White' }, @{ Name = 'Write-SymboledProgressI18n'; Symbol = '[~]'; SymbolColor = 'Gray'; MessageColor = 'White'; SequenceColor = 'White' }, @{ Name = 'Write-SymboledExitI18n'; Symbol = '[/]'; SymbolColor = 'Yellow'; MessageColor = 'White'; SequenceColor = 'White' }, @{ Name = 'Write-SymboledSuccessI18n'; Symbol = '[+]'; SymbolColor = 'Green'; MessageColor = 'White'; SequenceColor = 'White' }, @{ Name = 'Write-SymboledInvalidI18n'; Symbol = '[-]'; SymbolColor = 'Red'; MessageColor = 'White'; SequenceColor = 'White' } ) function New-SymboledI18nWrapperScriptBlock($Def) { $body = @" [CmdletBinding()] param( [Parameter(Position = 0, Mandatory = `$true)] [string]`$MessageKey, [Parameter(Position = 1)] [string]`$SequenceKey, [Parameter(Position = 2)] [object[]]`$MessageFormatArgs, [ConsoleColor]`$SymbolColor = '$($Def.SymbolColor)', [ConsoleColor]`$MessageColor = '$($Def.MessageColor)', [ConsoleColor]`$SequenceColor = '$($Def.SequenceColor)' ) Write-SymboledI18n '$($Def.Symbol -replace "'", "''")' `$MessageKey `$SequenceKey -MessageFormatArgs `$MessageFormatArgs -SymbolColor `$SymbolColor -MessageColor `$MessageColor -SequenceColor `$SequenceColor "@ $code = "function $($Def.Name) { $body }" $errors = $null $result = [System.Management.Automation.Language.Parser]::ParseInput($code, $null, [ref]$null, [ref]$errors) $errors | ForEach-Object { Write-Warning $_ } $result.GetScriptBlock() } foreach ($def in $script:SymboledI18nWrapperDefs) { . (New-SymboledI18nWrapperScriptBlock $def) } |