mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2026-11-11 06:47:21 +00:00
Added the informal address to the BeyondFacts Lab (#1176)
This commit is contained in:
1 parent
b6c3fbb5db
commit
e77645f44c
48 files changed
+1254
-160
No files matched your search
@@ -0,0 +1,43 @@
|
||||
namespace SharedTools;
|
||||
|
||||
/// <summary>
|
||||
/// Names the keys of the two variants of a text with TA(), which addresses the reader.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Many languages tell a formal address from an informal one, such as "Sie" and "du" in German. A text with TA()
|
||||
/// therefore has two keys: its usual key, whose translation addresses the reader formally like all texts of the
|
||||
/// app, and the same key with INFORMAL_SUFFIX, whose translation addresses the reader informally. The I18N
|
||||
/// collector writes both keys, and the app looks up the informal one when the person wants to be addressed so.
|
||||
/// </remarks>
|
||||
public static class I18NAddressVariant
|
||||
{
|
||||
/// <summary>
|
||||
/// The end of the key of the variant with the informal address.
|
||||
/// </summary>
|
||||
public const string INFORMAL_SUFFIX = "::INFORMAL";
|
||||
|
||||
/// <summary>
|
||||
/// Gets the key of the variant with the informal address.
|
||||
/// </summary>
|
||||
/// <param name="key">The usual key of the text, which stands for the formal address.</param>
|
||||
/// <returns>The key of the informal variant.</returns>
|
||||
public static string InformalKeyOf(string key) => $"{key}{INFORMAL_SUFFIX}";
|
||||
|
||||
/// <summary>
|
||||
/// Tries to get the usual key of a text from the key of its informal variant.
|
||||
/// </summary>
|
||||
/// <param name="key">Any key.</param>
|
||||
/// <param name="formalKey">The usual key of the text, or the given key when it belongs to no informal variant.</param>
|
||||
/// <returns>True, when the given key belongs to an informal variant.</returns>
|
||||
public static bool TryGetFormalKey(string key, out string formalKey)
|
||||
{
|
||||
if (key.EndsWith(INFORMAL_SUFFIX, StringComparison.Ordinal))
|
||||
{
|
||||
formalKey = key[..^INFORMAL_SUFFIX.Length];
|
||||
return true;
|
||||
}
|
||||
|
||||
formalKey = key;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,15 +1,18 @@
|
||||
namespace SharedTools;
|
||||
|
||||
/// <summary>
|
||||
/// Finds the texts of T() and TB() in a C# or Razor source file.
|
||||
/// Finds the texts of T(), TB(), and TA() in a C# or Razor source file.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// A text counts when its literal follows the opening parenthesis right away and is the whole first argument.
|
||||
/// Every kind of literal works, also a raw literal over several lines; see CSharpStringLiteral.
|
||||
/// Every kind of literal works, also a raw literal over several lines; see CSharpStringLiteral. A text of TA()
|
||||
/// addresses the reader, so it gets a variant with the informal address; see I18NAddressVariant.
|
||||
/// </remarks>
|
||||
public static class I18NSourceScanner
|
||||
{
|
||||
private static readonly string[] START_TAGS = ["TB(", "T("];
|
||||
private const string ADDRESSED_TEXT_TAG = "TA(";
|
||||
|
||||
private static readonly string[] START_TAGS = ["TB(", ADDRESSED_TEXT_TAG, "T("];
|
||||
|
||||
/// <summary>
|
||||
/// Finds the texts in the content of a source file.
|
||||
@@ -22,7 +25,7 @@ public static class I18NSourceScanner
|
||||
{
|
||||
var texts = new List<I18NSourceText>();
|
||||
var position = 0;
|
||||
while (TryFindNextCall(content, position, out var literalStart))
|
||||
while (TryFindNextCall(content, position, out var literalStart, out var tag))
|
||||
{
|
||||
position = literalStart;
|
||||
var rest = content.AsSpan(literalStart);
|
||||
@@ -49,29 +52,30 @@ public static class I18NSourceScanner
|
||||
continue;
|
||||
}
|
||||
|
||||
texts.Add(new I18NSourceText(literalStart, length, text));
|
||||
texts.Add(new I18NSourceText(literalStart, length, text, tag == ADDRESSED_TEXT_TAG));
|
||||
}
|
||||
|
||||
return texts;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds the next call of T() or TB() at or after the position, i.e., a start tag which no identifier precedes.
|
||||
/// Finds the next call of T(), TB(), or TA() at or after the position, i.e., a start tag which no identifier precedes.
|
||||
/// </summary>
|
||||
private static bool TryFindNextCall(string content, int position, out int argumentStart)
|
||||
private static bool TryFindNextCall(string content, int position, out int argumentStart, out string foundTag)
|
||||
{
|
||||
argumentStart = -1;
|
||||
foundTag = string.Empty;
|
||||
while (position < content.Length)
|
||||
{
|
||||
var bestIndex = -1;
|
||||
var bestLength = 0;
|
||||
var bestTag = string.Empty;
|
||||
foreach (var tag in START_TAGS)
|
||||
{
|
||||
var index = content.IndexOf(tag, position, StringComparison.Ordinal);
|
||||
if (index >= 0 && (bestIndex < 0 || index < bestIndex))
|
||||
{
|
||||
bestIndex = index;
|
||||
bestLength = tag.Length;
|
||||
bestTag = tag;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,7 +88,8 @@ public static class I18NSourceScanner
|
||||
continue;
|
||||
}
|
||||
|
||||
argumentStart = bestIndex + bestLength;
|
||||
argumentStart = bestIndex + bestTag.Length;
|
||||
foundTag = bestTag;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
namespace SharedTools;
|
||||
|
||||
/// <summary>
|
||||
/// A text of T() or TB() which the I18N collector found in a source file.
|
||||
/// A text of T(), TB(), or TA() which the I18N collector found in a source file.
|
||||
/// </summary>
|
||||
/// <param name="Offset">Where its literal starts in the file.</param>
|
||||
/// <param name="Length">How many characters its literal takes in the file.</param>
|
||||
/// <param name="Text">The string the compiler makes of the literal.</param>
|
||||
public sealed record I18NSourceText(int Offset, int Length, string Text);
|
||||
/// <param name="HasAddressVariants">Whether the text comes from TA(), i.e., addresses the reader and gets a variant with the informal address, see I18NAddressVariant.</param>
|
||||
public sealed record I18NSourceText(int Offset, int Length, string Text, bool HasAddressVariants);
|
||||
Reference in new issue
Block a user