Skip to content

Commit

Permalink
Add fluent function for indefinite article (#2805)
Browse files Browse the repository at this point in the history
  • Loading branch information
mirrorcult authored Jun 6, 2022
1 parent 4ab43cc commit 3941930
Showing 1 changed file with 103 additions and 0 deletions.
103 changes: 103 additions & 0 deletions Robust.Shared/Localization/LocalizationManager.Functions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text.RegularExpressions;
using Linguini.Bundle;
using Linguini.Bundle.Types;
using Linguini.Shared.Types.Bundle;
Expand Down Expand Up @@ -35,6 +37,7 @@ private void AddBuiltInFunctions(FluentBundle bundle)
// Misc
AddCtxFunction(bundle, "ATTRIB", args => FuncAttrib(bundle, args));
AddCtxFunction(bundle, "CAPITALIZE", FuncCapitalize);
AddCtxFunction(bundle, "INDEFINITE", FuncIndefinite);
}

/// <summary>
Expand All @@ -56,6 +59,106 @@ private ILocValue FuncCapitalize(LocArgs args)
else return new LocValueString("");
}

private static readonly string[] IndefExceptions = { "euler", "heir", "honest" };
private static readonly char[] IndefCharList = { 'a', 'e', 'd', 'h', 'i', 'l', 'm', 'n', 'o', 'r', 's', 'x' };
private static readonly Regex[] IndefRegexes =
{
new ("^e[uw]"),
new ("^onc?e\b"),
new ("^uni([^nmd]|mo)"),
new ("^u[bcfhjkqrst][aeiou]")
};

private static readonly Regex IndefRegexFjo =
new("(?!FJO|[HLMNS]Y.|RY[EO]|SQU|(F[LR]?|[HL]|MN?|N|RH?|S[CHKLMNPTVW]?|X(YL)?)[AEIOU])[FHLMNRSX][A-Z]");

private static readonly Regex IndefRegexU = new("^U[NK][AIEO]");

private static readonly Regex IndefRegexY =
new("^y(b[lor]|cl[ea]|fere|gg|p[ios]|rou|tt)");

private static readonly char[] IndefVowels = { 'a', 'e', 'i', 'o', 'u' };

private ILocValue FuncIndefinite(LocArgs args)
{
ILocValue val = args.Args[0];
if (val.Value == null)
return new LocValueString("an");

string? word;
string? input;
if (val.Value is EntityUid entity)
{
if (TryGetEntityLocAttrib(entity, "indefinite", out var indef))
return new LocValueString(indef);

input = _entMan.GetComponent<MetaDataComponent>(entity).EntityName;
}
else
{
input = val.Format(new LocContext());
}

if (String.IsNullOrEmpty(input))
return new LocValueString("");

var a = new LocValueString("a");
var an = new LocValueString("an");

var m = Regex.Match(input, @"\w+");
if (m.Success)
{
word = m.Groups[0].Value;
}
else
{
return an;
}

var wordi = word.ToLower();
if (IndefExceptions.Any(anword => wordi.StartsWith(anword)))
{
return an;
}

if (wordi.StartsWith("hour") && !wordi.StartsWith("houri"))
return an;

if (wordi.Length == 1)
{
return wordi.IndexOfAny(IndefCharList) == 0 ? an : a;
}

if (IndefRegexFjo.Match(word)
.Success)
{
return an;
}

foreach (var regex in IndefRegexes)
{
if (regex.IsMatch(wordi))
return a;
}

if (IndefRegexU.IsMatch(word))
{
return a;
}

if (word == word.ToUpper())
{
return wordi.IndexOfAny(IndefCharList) == 0 ? an : a;
}

if (wordi.IndexOfAny(IndefVowels) == 0)
{
return an;
}

return IndefRegexY.IsMatch(wordi) ? an : a;
}

/// <summary>
/// Returns the gender of the entity passed in; either Male, Female, Neuter or Epicene.
/// </summary>
Expand Down

0 comments on commit 3941930

Please sign in to comment.