Fix qps-ploc generation for store translations (#17526)

* Modified `Generate-PseudoLocalizations.ps1` to find the .xml files.
  (As opposed to .resw for the other translations.)
* Added support for the new format by adding new XPath expressions,
  and stripping comments/attributes as needed.
* Fixed `PreserveWhitespace` during XML loading.
* Fixed compliance with PowerShell's strict mode.

## Validation Steps Performed
Ran it locally and compared the results. 
This commit is contained in:
Leonard Hecker 2024-07-09 00:26:16 +02:00 committed by GitHub
parent bc20225b08
commit 5bbd905ded
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 71 additions and 33 deletions

View File

@ -1,5 +1,5 @@
Get-ChildItem -Recurse -Filter *.resw
| Where-Object { $_.Directory.Name.StartsWith("qps-ploc") }
Get-ChildItem -Recurse -Directory -Filter qps-ploc*
| Get-ChildItem -Include *.resw,*.xml
| ForEach-Object {
$source = Join-Path $_.Directory "../en-US/$($_.Name)"
$target = $_

View File

@ -1,5 +1,5 @@
param(
[Parameter(Mandatory=$True)]
[Parameter(Mandatory = $True)]
[string]$Path
)
@ -55,20 +55,25 @@ $mapping['Y'[0]] = '¥ÝŶΎΥΫỲЎ'
$mapping['z'[0]] = 'źżž'
$mapping['Z'[0]] = 'ŹŻΖŽ'
[xml]$content = Get-Content $Path
$content = [System.Xml.XmlDocument]::new()
$content.PreserveWhitespace = $true
$content.Load($Path)
function GetPseudoLocalization([string]$key, [string]$value, [string]$comment) {
$locked = $null
if ($comment -match '.*\{Locked=?([^}]*)\}.*') {
$locked = $Matches[1]
}
# Skip {Locked} and {Locked=qps-ploc} entries
if ($locked -and (($locked -eq '') -or $locked.Contains('qps-ploc'))) {
continue
}
foreach ($entry in $content.root.data) {
$value = $entry.value
$comment = $entry.comment ?? ''
$placeholders = @{}
if ($comment.StartsWith('{Locked')) {
# Skip {Locked} and {Locked=qps-ploc} entries
if ($comment -match '\{Locked(\}|=[^}]*qps-ploc).*') {
continue
}
$lockedList = ($comment -replace '\{Locked=(.*?)\}.*','$1') -split ','
if ($locked) {
$lockedList = $locked -split ','
$placeholderChar = 0xE000
# Replaced all locked words with placeholders from the Unicode Private Use Area
@ -86,34 +91,67 @@ foreach ($entry in $content.root.data) {
}
}
# We can't rely on $entry.name.GetHashCode() to be consistent across different runs,
# We can't rely on $key.GetHashCode() to be consistent across different runs,
# because in the future PowerShell may enable UseRandomizedStringHashAlgorithm.
$hash = [System.Text.Encoding]::UTF8.GetBytes($entry.name)
$hash = [System.Text.Encoding]::UTF8.GetBytes($key)
$hash = [System.Security.Cryptography.SHA1]::Create().ComputeHash($hash)
$hash = [System.BitConverter]::ToInt32($hash)
# Replace all characters with pseudo-localized characters
$rng = [System.Random]::new($hash)
$newValue = ''
foreach ($char in $value.ToCharArray()) {
if ($m = $mapping[$char]) {
$newValue += $m[$rng.Next(0, $mapping[$char].Length)]
} else {
$newValue += $char
$lines = $value.Split("`n")
$lines = $lines | ForEach-Object {
# Replace all characters with pseudo-localized characters
$newValue = ''
foreach ($char in $_.ToCharArray()) {
if ($m = $mapping[$char]) {
$newValue += $m[$rng.Next(0, $mapping[$char].Length)]
}
else {
$newValue += $char
}
}
# Replace all placeholders with their original values
foreach ($kv in $placeholders.GetEnumerator()) {
$newValue = $newValue.Replace($kv.Key, $kv.Value)
}
# Add 40% padding to the end of the string
$paddingLength = [System.Math]::Round(0.4 * $_.Length)
$padding = ' !!!' * ($paddingLength / 4 + 1)
$newValue + $padding.Substring(0, $paddingLength)
}
return $lines -join "`n"
}
if ($path.EndsWith(".resw")) {
foreach ($entry in $content.SelectNodes('/root/data')) {
$comment = $entry.SelectSingleNode('comment')?.'#text' ?? ''
$entry.value = GetPseudoLocalization $entry.name $entry.value $comment
}
}
elseif ($path.EndsWith(".xml")) {
foreach ($parent in $content.DocumentElement.SelectNodes('//*[@_locID]')) {
$locID = $parent.GetAttribute('_locID')
$comment = $parent.SelectSingleNode('comment()[contains(., "_locComment_text")]')?.'#text' ?? ''
foreach ($entry in $parent.SelectNodes('text()')) {
$value = $entry.Value
if ($value.Trim().Length -ne 0) {
$entry.Value = GetPseudoLocalization $locID $value $comment
}
}
}
# Replace all placeholders with their original values
foreach ($kv in $placeholders.GetEnumerator()) {
$newValue = $newValue.Replace($kv.Key, $kv.Value)
# Remove all _locComment_text comments
foreach ($entry in $content.DocumentElement.SelectNodes('//comment()[contains(., "_locComment_text")]')) {
$null = $entry.ParentNode.RemoveChild($entry)
}
# Add 40% padding to the end of the string
$paddingLength = [System.Math]::Round(0.4 * $newValue.Length)
$padding = ' !!!' * ($paddingLength / 4 + 1)
$newValue += $padding.Substring(0, $paddingLength)
$entry.value = $newValue
# Remove all _locID attributes
foreach ($entry in $content.DocumentElement.SelectNodes('//*[@_locID]')) {
$entry.RemoveAttribute('_locID')
}
}
return $content