Skip to content

Commit 7fa7c9f

Browse files
committed
Fix Ascii banners for Asian languages
1 parent 2247e1b commit 7fa7c9f

File tree

1 file changed

+44
-3
lines changed

1 file changed

+44
-3
lines changed

Src/Private/Draw-AsciiBanner.ps1

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ function Draw-AsciiBanner {
66
Draws a decorative ASCII banner box with rounded corners around one or more lines of text.
77
Uses Unicode box-drawing characters for a clean, modern appearance in the console.
88
Supports customizable text and border colors, and adjustable padding.
9+
Properly handles double-width characters (CJK, emoji, etc.) for correct alignment.
910
.PARAMETER Lines
1011
An array of strings to display inside the banner. Each string will be centered on its own line.
1112
.PARAMETER TextColor
@@ -26,6 +27,7 @@ function Draw-AsciiBanner {
2627
.NOTES
2728
This is a private function used internally by the AsBuiltReport.Core module.
2829
Uses Unicode box-drawing characters (U+256D, U+256E, U+2570, U+256F, U+2500, U+2502) for PS 5.1 compatibility.
30+
Calculates display width accounting for double-width characters (CJK ideographs, full-width forms, etc.).
2931
#>
3032
param(
3133
[string[]]$Lines,
@@ -34,8 +36,46 @@ function Draw-AsciiBanner {
3436
[int]$ExtraPadding = 2
3537
)
3638

37-
$maxLen = ($Lines | Measure-Object Length -Maximum).Maximum
38-
$contentWidth = $maxLen + ($ExtraPadding * 2)
39+
# Helper function to calculate display width of a string
40+
# Accounts for double-width characters (CJK, emoji, etc.)
41+
function Get-DisplayWidth {
42+
param([string]$Text)
43+
44+
$width = 0
45+
foreach ($char in $Text.ToCharArray()) {
46+
$codePoint = [int][char]$char
47+
48+
# Check if character is double-width
49+
# CJK Unified Ideographs: U+4E00-U+9FFF
50+
# CJK Extension A: U+3400-U+4DBF
51+
# Hangul Syllables: U+AC00-U+D7AF
52+
# Hiragana/Katakana: U+3040-U+30FF
53+
# Full-width Forms: U+FF00-U+FFEF
54+
# CJK Symbols and Punctuation: U+3000-U+303F
55+
if (($codePoint -ge 0x4E00 -and $codePoint -le 0x9FFF) -or
56+
($codePoint -ge 0x3400 -and $codePoint -le 0x4DBF) -or
57+
($codePoint -ge 0xAC00 -and $codePoint -le 0xD7AF) -or
58+
($codePoint -ge 0x3040 -and $codePoint -le 0x30FF) -or
59+
($codePoint -ge 0xFF00 -and $codePoint -le 0xFFEF) -or
60+
($codePoint -ge 0x3000 -and $codePoint -le 0x303F)) {
61+
$width += 2
62+
} else {
63+
$width += 1
64+
}
65+
}
66+
return $width
67+
}
68+
69+
# Calculate max display width across all lines
70+
$maxDisplayWidth = 0
71+
foreach ($line in $Lines) {
72+
$displayWidth = Get-DisplayWidth -Text $line
73+
if ($displayWidth -gt $maxDisplayWidth) {
74+
$maxDisplayWidth = $displayWidth
75+
}
76+
}
77+
78+
$contentWidth = $maxDisplayWidth + ($ExtraPadding * 2)
3979

4080
# Top and bottom borders - use Unicode code points for PS 5.1 compatibility
4181
$topLeft = [char]0x256D #
@@ -50,7 +90,8 @@ function Draw-AsciiBanner {
5090

5191
Write-Host $top -ForegroundColor $BorderColor
5292
foreach ($line in $Lines) {
53-
$totalPadding = $contentWidth - $line.Length
93+
$lineDisplayWidth = Get-DisplayWidth -Text $line
94+
$totalPadding = $contentWidth - $lineDisplayWidth
5495
$leftPad = [math]::Floor($totalPadding / 2)
5596
$rightPad = $totalPadding - $leftPad
5697
$padded = (' ' * $leftPad) + $line + (' ' * $rightPad)

0 commit comments

Comments
 (0)