Skip to content

Commit 65e8a92

Browse files
Anatoly Bolshakovkuleshovilya
andauthored
Localization update (#136)
* Removing Localize folder * Revert "Removing Localize folder" Co-authored-by: Ilya Kuleshov <[email protected]>
1 parent 1ff222b commit 65e8a92

File tree

400 files changed

+49978
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

400 files changed

+49978
-0
lines changed
Binary file not shown.
Lines changed: 384 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,384 @@
1+
<#
2+
.DESCRIPTION
3+
Resource parser for Android .xml files.
4+
5+
.SYNOPSIS
6+
7+
.PARAMETER
8+
Hidden parameters from the AnyParse host.
9+
10+
[string]$filePath # Path of the file to be read/write.
11+
[int]$parentDbid # Internal parent id to create content nodes.
12+
[int]$langIDSrc # Source language lcid.
13+
[CultureInfo]$langCultureInfoSrc # Source language CultureInfo.
14+
[int]$langIDTgt # Target language lcid.
15+
[CultureInfo]$langCultureInfoTgt # Target language CultureInfo.
16+
[bool]$isGenerating # True if generating the target file.
17+
18+
.LINK
19+
https://osgwiki.com/wiki/AnyParse
20+
21+
.NOTES
22+
02/2021
23+
mailto:[email protected]?subject=AnyParse
24+
#>
25+
26+
<#
27+
# Debug
28+
#
29+
# Default output file gets deleted by the parser.
30+
$filePath = "D:\test\android\Android_strings.xml"
31+
$debugFilePath = "$($filePath).debug.xml"
32+
Copy-Item $filePath -Destination $debugFilePath
33+
$filePath = $debugFilePath
34+
35+
$isGenerating = $true
36+
37+
class ParserStub {
38+
[void]SubmitNode([ref]$parentDBID, [int]$displayParent, [nullable[int]]$numResType, [string]$strResType, [string]$nodeName, [bool]$isExpandable, [bool]$visible, $iconType) {
39+
}
40+
41+
[string]SubmitResource([int]$parentDBID, [nullable[int]]$numResType, [string]$strResType, [nullable[int]]$numResID, [string]$strResID, [string]$resStr, [string]$comment, [string]$termNote, [bool]$isGenerating) {
42+
Write-Host "Comment='$comment'"
43+
Write-Host "id='$strResID', text='$resStr'"
44+
return "[😺 $([char]0x2122) (tm) ソボミダゾ$resStr !!! !!! !!! ]"
45+
}
46+
47+
[void]LogInfo([string]$msg) {
48+
Write-Host "Info: $msg"
49+
}
50+
51+
[void]LogWarning([string]$msg) {
52+
Write-Host "Warning: $msg"
53+
}
54+
55+
[void]LogError([string]$msg) {
56+
Write-Host "Error: $msg"
57+
}
58+
}
59+
60+
Add-Type @'
61+
namespace ManagedLSOM
62+
{
63+
public class ELSIconType
64+
{
65+
public static int elsIconString = 9;
66+
}
67+
}
68+
'@
69+
70+
$this = New-Object ParserStub
71+
$langCultureInfoTgt = [System.Globalization.CultureInfo]::GetCultureInfo(1025) # 1025=ar-SA, 1041=ja-JP
72+
$langIDTgt = $langCultureInfoTgt.LCID
73+
$ScriptRoot = "."
74+
#>
75+
76+
Add-Type -Path $ScriptRoot/ICUParserLib.dll
77+
78+
# Setup variables.
79+
# Regex for the char limit instruction.
80+
[string]$maxLengthRegex = '\[\s*CHAR.LIMIT\s*=\s*(?<MaxLength>\d+)\s*\]'
81+
82+
# Additional help strings to be added for plural resources.
83+
$androidPluralHelpStrings = @{
84+
zero = "NOTE: Leave this value the same as 'other' if the language does not require special treatment for it. When the language requires special treatment of the number 0 (as in Arabic)."
85+
one = "NOTE: When the language requires special treatment of numbers like one (as with the number 1 in English and most other languages; in Russian, any number ending in 1 but not ending in 11 is in this class)."
86+
two = "NOTE: When the language requires special treatment of numbers like two (as with 2 in Welsh, or 102 in Slovenian)."
87+
few = "NOTE: When the language requires special treatment of small numbers (as with 2, 3, and 4 in Czech; or numbers ending 2, 3, or 4 but not 12, 13, or 14 in Polish)."
88+
many = "NOTE: When the language requires special treatment of large numbers (as with numbers ending 11-99 in Maltese)."
89+
other = "NOTE: When the language does not require special treatment of the given quantity (as with all numbers in Chinese, or 42 in English)."
90+
}
91+
92+
<#
93+
.DESCRIPTION
94+
Submit item.
95+
Preserve CDATA structure of the resource.
96+
#>
97+
function Submit-Item(
98+
[int]$childDbid,
99+
[System.Xml.XmlDocument]$xml,
100+
[System.Xml.XmlElement]$readNode,
101+
[System.Xml.XmlElement]$writeNode,
102+
[string]$stringId,
103+
[string]$text,
104+
[string]$devComment,
105+
[bool]$isGenerating
106+
) {
107+
$text = $this.SubmitResource($childDbid, 42, "XML:Text", 0, $stringId, $text, $devComment, "", $isGenerating) -replace "(?<!\\)'", "\'" # add escaping to single apostrophe
108+
109+
if ($isGenerating) {
110+
try {
111+
# Preserve CDATA structure of the resource.
112+
if ($readNode.HasChildNodes -and $readNode.ChildNodes[0].NodeType -eq "CDATA") {
113+
$writeNode.InnerXml = $xml.CreateCDataSection($text).OuterXml
114+
}
115+
else {
116+
$writeNode.InnerXml = $text
117+
}
118+
}
119+
catch {
120+
throw [System.IO.InvalidDataException] "Invalid translation for resourceID '$stringId'`nTranslation: '$text'`nTargetculture: '$($langCultureInfoTgt.Name)'`nFilename: '$filePath'`nError: '$_'"
121+
}
122+
}
123+
}
124+
125+
<#
126+
.DESCRIPTION
127+
Gets the src item.
128+
#>
129+
function Get-SrcItem([System.Xml.XmlElement]$node) {
130+
# Support CDATA tags in Android.
131+
if ($node.HasChildNodes -and $node.ChildNodes[0].NodeType -eq "CDATA") {
132+
$node.InnerText
133+
}
134+
else {
135+
$node.InnerXml
136+
}
137+
}
138+
139+
<#
140+
.DESCRIPTION
141+
Gets the individual comment for the node.
142+
#>
143+
function Get-IndividualComment([System.Xml.XmlElement]$node) {
144+
if ($node.NextSibling.NodeType -eq "Comment") {
145+
return " | " + $node.NextSibling.value.trim()
146+
}
147+
elseif ($node.NextSibling.NodeType -eq "Whitespace" -and
148+
-not $node.NextSibling.value.Contains("`n") -and
149+
$node.NextSibling.NextSibling.NodeType -eq "Comment" ) {
150+
return " | " + $node.NextSibling.NextSibling.value.trim()
151+
}
152+
""
153+
}
154+
155+
<#
156+
.DESCRIPTION
157+
Gets the comment and converts the optional CHAR_LIMIT to a LocVer instruction.
158+
#>
159+
function Get-Comment([string]$text, [string]$devComment) {
160+
# Protect content tags.
161+
[System.Text.RegularExpressions.MatchCollection]$tags = ([regex]::Matches($text, '<.+?>'))
162+
163+
# Check if CHAR_LIMIT is used.
164+
[int]$maxLengthValue = -1
165+
if ($devComment -match $maxLengthRegex) {
166+
[string]$maxLength = $matches['MaxLength']
167+
$maxLengthValue = [int]$maxLength
168+
169+
# Add the length of the placeholders to the CHAR_LIMIT value as the new MaxLength instruction.
170+
if ($maxLengthValue -gt 0) {
171+
# Remove CHAR_LIMIT
172+
$devComment = $devComment -replace $maxLengthRegex, ""
173+
174+
[int]$tagsLength = $maxLengthValue
175+
$tags | % { $tagsLength += $_.Length }
176+
if ($tagsLength -gt 0) {
177+
$devComment += " {MaxLength=$tagsLength}"
178+
}
179+
}
180+
}
181+
182+
# Add LocVer Placeholder instructions for the tags.
183+
$tagsUnique = $tags | Select-Object -unique
184+
[string]$placeholder = $tagsUnique | % { " {Placeholder=`"$_`"}" }
185+
$devComment + $placeholder
186+
}
187+
188+
# Read the android .xml file.
189+
[xml]$xml = New-Object xml
190+
$xml.PreserveWhitespace = $true
191+
$xml.Load($filePath)
192+
193+
# Debug: save copy with the default formatting to simplify compare with the generated file.
194+
#$xml.Save($filePath + ".formatted.xml")
195+
196+
# Create the parent '<string>' node.
197+
[int]$childDbid = $parentDbid
198+
$this.SubmitNode([ref]$childDbid, 0, 0, $null, "<string>", $true, $true, [ManagedLSOM.ELSIconType]::elsIconString)
199+
200+
# Select all child nodes.
201+
$stringNodes = $xml.SelectNodes("/resources/child::node()")
202+
203+
# Support group comment headers.
204+
[string]$groupComment = ""
205+
206+
# Enumerate each node and get the loc content.
207+
foreach ($stringNode in $stringNodes) {
208+
#$this.LogInfo($groupComment)
209+
210+
# Skip whitespace nodes.
211+
if ($stringNode.NodeType -eq "Whitespace") {
212+
continue
213+
}
214+
215+
# Add group comment to dev comments.
216+
# Group comment is defined by a leading line:
217+
# <!-- group comment1 -->
218+
# <string name="action_settings">Settings</string>
219+
if ($stringNode.NodeType -eq "Comment" -and
220+
$stringNode.PreviousSibling.NodeType -eq "Whitespace" -and
221+
$stringNode.PreviousSibling.value.Contains("`n")
222+
) {
223+
$groupComment = $stringNode.value.trim()
224+
continue
225+
}
226+
227+
# Skip nodes with the translatable attribute set to false.
228+
if ($stringNode."translatable" -eq "false") {
229+
continue
230+
}
231+
232+
if ($stringNode.LocalName -eq "string") {
233+
234+
# Get resource id from the name attribute.
235+
[string]$stringId = $stringNode."name"
236+
237+
# Get source text.
238+
[string]$text = Get-SrcItem $stringNode
239+
240+
# Get dev comment.
241+
[string]$devComment = Get-Comment $text $stringNode."comment"
242+
243+
if ($groupComment) {
244+
$devComment += " | " + $groupComment
245+
}
246+
247+
# Add individual comment.
248+
# Individual comment follows directly the content node:
249+
# <string name="action_manage_accounts">Manage Accounts</string><!-- individual comment -->
250+
$devComment += Get-IndividualComment $stringNode
251+
252+
# Submit item.
253+
Submit-Item $childDbid $xml $stringNode $stringNode $stringId $text $devComment $isGenerating
254+
}
255+
elseif ($stringNode.LocalName -eq "string-array") {
256+
257+
# Get resource id from the name attribute.
258+
[string]$stringId = $stringNode."name"
259+
260+
# Get dev comment.
261+
[string]$comment = $stringNode."comment"
262+
263+
# array ids start with 1
264+
[int]$arrayId = 1
265+
foreach ($childNode in $stringNode.SelectNodes("item")) {
266+
# Compose the item id from the parent id and the array id.
267+
[string]$itemStringId = "string-array_$($stringId)_$($arrayId)"
268+
$arrayId++
269+
270+
# Get item source text.
271+
[string]$itemText = Get-SrcItem $childNode
272+
273+
# Get dev comment.
274+
[string]$devComment = "$($itemStringId). For item: $($itemText)" + (Get-Comment $itemText $comment)
275+
276+
# Get item dev comment.
277+
[string]$itemDevComment = $devComment
278+
[string]$itemComment = $childNode."comment"
279+
280+
if ($itemComment) {
281+
$itemDevComment += " | " + $itemComment
282+
}
283+
284+
if ($groupComment) {
285+
$itemDevComment += " | " + $groupComment
286+
}
287+
288+
# Add individual comment.
289+
# Individual comment follows directly the content node:
290+
# <string name="action_manage_accounts">Manage Accounts</string><!-- individual comment -->
291+
$itemDevComment += Get-IndividualComment $childNode
292+
293+
# Submit item.
294+
Submit-Item $childDbid $xml $childNode $childNode $itemStringId $itemText $itemDevComment $isGenerating
295+
}
296+
}
297+
elseif ($stringNode.LocalName -eq "plurals") {
298+
299+
# Get resource id from the name attribute.
300+
[string]$stringId = $stringNode."name"
301+
302+
# Get comment from the comment attribute.
303+
[string]$comment = $stringNode."comment"
304+
305+
# Get the node 'other' for the data type.
306+
[System.Xml.XmlElement]$itemOtherNode = $stringNode.SelectSingleNode("item[@quantity='other']")
307+
if (-not $itemOtherNode) {
308+
$this.LogError("The resource with id '$stringId' does not have the required quantity attribute 'other'.")
309+
return
310+
}
311+
312+
# Store the current plurals.
313+
[hashtable]$pluralMap = @{}
314+
315+
foreach ($childNode in $stringNode.SelectNodes("item")) {
316+
# Get resource id from the quantity attribute.
317+
[string]$quantity = $childNode."quantity"
318+
319+
# Get item source text.
320+
[string]$itemText = Get-SrcItem $childNode
321+
322+
$pluralMap[$quantity] = $itemText
323+
324+
# Keep the plural 'other'.
325+
if ($isGenerating -and $quantity -ne "other") {
326+
[void]($stringNode.RemoveChild($childNode))
327+
}
328+
}
329+
330+
# Expand the plural list.
331+
[System.Globalization.CultureInfo]$language = $null
332+
if ($isGenerating) {
333+
$language = $langCultureInfoTgt
334+
}
335+
336+
$messageItems = [ICUParserLib.ICUParser]::ExpandPlurals($pluralMap, $language)
337+
foreach ($messageItem in $messageItems) {
338+
[string]$text = $messageItem.Text
339+
[string]$quantity = $messageItem.ResourceId
340+
341+
# Compose the item id from the parent id and the array id.
342+
[string]$itemStringId = "plurals_$($stringId)_$($quantity)"
343+
344+
# Get dev comment.
345+
[string]$devComment = Get-Comment $text $comment
346+
347+
# Compose the item dev comment.
348+
[string]$helpString = $androidPluralHelpStrings[$quantity]
349+
[string]$itemDevComment = "Variant of plurals: $stringId. For amount: $quantity. $helpString $devComment"
350+
351+
# Add language specific lock.
352+
if ($messageItem.Data) {
353+
$itemDevComment += " (ICU){Locked=$($messageItem.Data)}"
354+
}
355+
356+
# Add group comment.
357+
if ($groupComment) {
358+
$itemDevComment += " | " + $groupComment
359+
}
360+
361+
# Add the plural.
362+
[System.Xml.XmlElement]$newItemNode = $itemOtherNode
363+
if ($quantity -ne "other") {
364+
$newItemNode = $xml.CreateElement("item")
365+
$newItemNode.SetAttribute("quantity", $quantity)
366+
[void]($stringNode.InsertBefore($newItemNode, $itemOtherNode))
367+
}
368+
369+
# Submit item.
370+
Submit-Item $childDbid $xml $itemOtherNode $newItemNode $itemStringId $text $itemDevComment $isGenerating
371+
}
372+
}
373+
}
374+
375+
if ($isGenerating) {
376+
377+
# Remove all non translatable strings.
378+
$nonTranslatableNodes = $xml.SelectNodes("//string[@translatable='false']")
379+
foreach ($nonTranslatableNode in $nonTranslatableNodes) {
380+
[void]($nonTranslatableNode.ParentNode.RemoveChild($nonTranslatableNode))
381+
}
382+
383+
$xml.Save($filePath)
384+
}
Binary file not shown.
Binary file not shown.

0 commit comments

Comments
 (0)