mirror of
https://github.com/space-syndicate/space-station-14.git
synced 2026-02-15 01:15:13 +01:00
[Wiki] loc fix 2 (#3484)
This commit is contained in:
@@ -29,19 +29,18 @@ public static class LocJsonGenerator
|
||||
.Where(c => c.Filename.EndsWith(".ftl", StringComparison.InvariantCultureIgnoreCase))
|
||||
.ToArray();
|
||||
var keys = new Dictionary<string, HashSet<string>>();
|
||||
var keysValues = new Dictionary<string, string>();
|
||||
|
||||
// Matches top-level message/term identifiers at start of line (no leading whitespace or comment).
|
||||
var topEntryRegex = new Regex(@"(?m)^(?!\s|#)([^\s=]+)\s*=", RegexOptions.Compiled);
|
||||
var topEntryRegex = new Regex(@"^(?!\s|#)([^\s=]+)\s*=", RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.CultureInvariant);
|
||||
// Matches attribute lines like " .attr-name ="
|
||||
var attrRegex = new Regex(@"(?m)^\s*\.(?<name>[A-Za-z0-9_\-]+)\s*=", RegexOptions.Compiled);
|
||||
var attrRegex = new Regex(@"^\s*\.(?<name>[A-Za-z0-9_\-]+)\s*=", RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.CultureInvariant);
|
||||
|
||||
foreach (var path in files)
|
||||
{
|
||||
using var stream = res.ContentFileRead(path);
|
||||
using var reader = new StreamReader(stream, Encoding.UTF8);
|
||||
var contents = reader.ReadToEnd();
|
||||
// Normalize line endings to simplify indexing.
|
||||
contents = contents.Replace("\r\n", "\n");
|
||||
var contents = reader.ReadToEnd().Replace("\r\n", "\n");
|
||||
|
||||
var matches = topEntryRegex.Matches(contents);
|
||||
for (var mi = 0; mi < matches.Count; mi++)
|
||||
@@ -57,13 +56,66 @@ public static class LocJsonGenerator
|
||||
var start = m.Index;
|
||||
var end = mi + 1 < matches.Count ? matches[mi + 1].Index : contents.Length;
|
||||
var block = contents.Substring(start, end - start);
|
||||
|
||||
var attrMatches = attrRegex.Matches(block);
|
||||
foreach (Match am in attrMatches)
|
||||
|
||||
var mainEqual = block.IndexOf('=');
|
||||
if (mainEqual >= 0)
|
||||
{
|
||||
var mainValueStart = mainEqual + 1;
|
||||
var mainValueEnd = attrMatches.Count > 0 ? attrMatches[0].Index : block.Length;
|
||||
keysValues[id] = mainValueEnd > mainValueStart ? FluentValue(block.Substring(mainValueStart, mainValueEnd - mainValueStart)) : string.Empty;
|
||||
}
|
||||
else
|
||||
{
|
||||
keysValues[id] = string.Empty;
|
||||
}
|
||||
|
||||
for (var ai = 0; ai < attrMatches.Count; ai++)
|
||||
{
|
||||
var am = attrMatches[ai];
|
||||
var attrName = am.Groups["name"].Value;
|
||||
if (!string.IsNullOrEmpty(attrName))
|
||||
keys[id].Add(attrName);
|
||||
if (string.IsNullOrEmpty(attrName))
|
||||
continue;
|
||||
keys[id].Add(attrName);
|
||||
|
||||
var attrEqual = block.IndexOf('=', am.Index);
|
||||
var attrValueStart = attrEqual >= 0 ? attrEqual + 1 : am.Index + am.Length;
|
||||
var nextAttrIndex = ai + 1 < attrMatches.Count ? attrMatches[ai + 1].Index : block.Length;
|
||||
keysValues[$"{id}.{attrName}"] = nextAttrIndex > attrValueStart ? FluentValue(block.Substring(attrValueStart, nextAttrIndex - attrValueStart)) : string.Empty;
|
||||
}
|
||||
|
||||
continue;
|
||||
|
||||
// Helper: remove leading newline and common indentation across non-empty lines.
|
||||
string FluentValue(string val)
|
||||
{
|
||||
if (string.IsNullOrEmpty(val))
|
||||
return string.Empty;
|
||||
|
||||
if (val.Length > 0 && val[0] == '\n')
|
||||
val = val.Substring(1);
|
||||
|
||||
var lines = val.Split('\n');
|
||||
lines = lines.Where(l => !(l.Length > 0 && l[0] == '#')).ToArray();
|
||||
var nonEmptyLines = lines.Where(l => !string.IsNullOrWhiteSpace(l)).ToArray();
|
||||
if (nonEmptyLines.Length == 0)
|
||||
return string.Join("\n", lines).TrimEnd('\n');
|
||||
|
||||
var minIndent = nonEmptyLines.Min(l => l.TakeWhile(char.IsWhiteSpace).Count());
|
||||
if (minIndent > 0)
|
||||
{
|
||||
for (var li = 0; li < lines.Length; li++)
|
||||
{
|
||||
var line = lines[li];
|
||||
if (line.Length >= minIndent)
|
||||
lines[li] = line.Substring(minIndent);
|
||||
}
|
||||
}
|
||||
|
||||
var result = string.Join("\n", lines);
|
||||
if (result.EndsWith("\n"))
|
||||
result = result.Substring(0, result.Length - 1);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -74,18 +126,18 @@ public static class LocJsonGenerator
|
||||
{
|
||||
if (attrs.Count == 0)
|
||||
{
|
||||
output[id] = Loc.GetString(id);
|
||||
output[id] = keysValues.TryGetValue(id, out var value) ? value : string.Empty;
|
||||
}
|
||||
else
|
||||
{
|
||||
// _value is the main value of the key.
|
||||
var obj = new Dictionary<string, string?>
|
||||
{
|
||||
["_value"] = Loc.GetString(id),
|
||||
["_value"] = keysValues.TryGetValue(id, out var valueMain) ? valueMain : string.Empty,
|
||||
};
|
||||
foreach (var attr in attrs.OrderBy(a => a))
|
||||
{
|
||||
obj[attr] = Loc.GetString($"{id}.{attr}");
|
||||
obj[attr] = keysValues.TryGetValue($"{id}.{attr}", out var valueAttr) ? valueAttr : string.Empty;
|
||||
}
|
||||
output[id] = obj;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user