using SharedTools;
namespace AIStudio.Assistants.I18N;
///
/// Tells the localization assistant how a text addresses the reader; see I18NAddressVariant.
///
///
/// The usual key of a text gets the formal address, like every text of the app. Its informal variant starts from
/// the formal translation and changes only the form of address, so that both variants read alike, and a formal
/// translation which a person reviewed carries its wording over. The formal translations therefore come first.
///
public static class I18NAddressPrompt
{
///
/// Puts the informal variants after all other texts and keeps the order otherwise.
///
/// The texts to translate, by their keys.
/// The texts in the order to translate them.
public static IReadOnlyList> FormalFirst(IEnumerable> content) => [.. content.OrderBy(entry => I18NAddressVariant.TryGetFormalKey(entry.Key, out _))];
///
/// Finds the formal translation of a text whose informal variant comes next.
///
/// The key of the informal variant.
/// The texts translated in this run.
/// The texts of the language plugin so far.
/// The formal translation, or null when there is none.
public static string? FindFormalTranslation(string informalKey, IReadOnlyDictionary translatedNow, IReadOnlyDictionary translatedBefore)
{
if (!I18NAddressVariant.TryGetFormalKey(informalKey, out var formalKey))
return null;
if (translatedNow.TryGetValue(formalKey, out var translation) && !string.IsNullOrWhiteSpace(translation))
return translation;
if (translatedBefore.TryGetValue(formalKey, out translation) && !string.IsNullOrWhiteSpace(translation))
return translation;
return null;
}
///
/// Gives every informal variant the words of its formal text, for a language with one form of address only.
///
///
/// English addresses everybody alike, yet its language plugin may word a text differently than the source code
/// does. An informal variant taken from the source code would then differ from the formal text, and the language
/// would offer the choice of address, see .
///
/// All texts of the language plugin, by their keys; changed in place.
public static void AlignInformalVariants(IDictionary content)
{
foreach (var key in content.Keys.ToList())
{
if (I18NAddressVariant.TryGetFormalKey(key, out var formalKey) && content.TryGetValue(formalKey, out var formalText))
content[key] = formalText;
}
}
///
/// Gets the section of the system prompt about the form of address.
///
/// The target language.
/// Whether the text is the informal variant of a text.
/// The formal translation of the text, when it is an informal variant and has one.
/// The section, as Markdown.
public static string Section(string language, bool isInformalVariant, string? formalTranslation)
{
if (!isInformalVariant)
return $"""
# Form of Address
When a text addresses the reader, use the formal address of {language}, such as "Sie" in
German, "vous" in French, or "usted" in Spanish.
""";
if (string.IsNullOrWhiteSpace(formalTranslation))
return $"""
# Form of Address
Address the reader informally, with the informal address of {language}, such as "du" in
German, "tu" in French, or "tú" in Spanish. When {language} has only one form of address,
translate as usual.
""";
return $"""
# Form of Address
Address the reader informally, with the informal address of {language}, such as "du" in
German, "tu" in French, or "tú" in Spanish. The formal translation of this text exists already:
{formalTranslation}
Keep its wording, its Markdown, and its line breaks, and change only what the informal address
requires, such as pronouns, possessives, and verb forms. When {language} has only one form of
address, answer with the formal translation unchanged.
""";
}
}