Skip to content

Instantly share code, notes, and snippets.

@karljj1
Last active January 15, 2024 17:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save karljj1/733e0e886ac7be94bb4408d25e3c900b to your computer and use it in GitHub Desktop.
Save karljj1/733e0e886ac7be94bb4408d25e3c900b to your computer and use it in GitHub Desktop.
Generate String Table Word Count Report
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using UnityEditor;
using UnityEditor.Localization;
using UnityEngine.Localization.Settings;
using UnityEngine.Localization.SmartFormat;
using UnityEngine.Localization.SmartFormat.Core.Extensions;
using UnityEngine.Localization.SmartFormat.Core.Formatting;
using UnityEngine.Localization.SmartFormat.Core.Parsing;
using UnityEngine.UIElements;
public class WordCount
{
// Extracts all literal characters from a SmartFormat string.
class SmartFormatterLiteralCharacterExtractor : SmartFormatter
{
IEnumerable<char> m_Characters;
public SmartFormatterLiteralCharacterExtractor(SmartFormatter parent)
{
Settings = parent.Settings;
Parser = parent.Parser;
SourceExtensions.AddRange(parent.SourceExtensions);
FormatterExtensions.AddRange(parent.FormatterExtensions);
}
public IEnumerable<char> ExtractLiteralsCharacters(string value)
{
m_Characters = "";
Format(value, null);
return m_Characters;
}
public override void Format(FormattingInfo formattingInfo)
{
foreach (var item in formattingInfo.Format.Items)
{
if (item is LiteralText literalItem)
{
m_Characters = m_Characters.Concat(item.ToEnumerable());
// Add a space between each literal
m_Characters = m_Characters.Concat(" ");
continue;
}
// Otherwise, the item must be a placeholder.
var placeholder = (Placeholder)item;
var childFormattingInfo = formattingInfo.CreateChild(placeholder);
var formatterName = childFormattingInfo.Placeholder.FormatterName;
// Evaluate the named formatter (or, evaluate all "" formatters)
foreach (var formatterExtension in FormatterExtensions)
{
if (formatterExtension is IFormatterLiteralExtractor literalExtractor &&
formatterExtension.Names.Contains(formatterName))
{
literalExtractor.WriteAllLiterals(childFormattingInfo);
}
}
}
}
}
[LocalizationExportMenu]
public static void ExportWordCount(LocalizationTableCollection collection, DropdownMenu menu)
{
menu.AppendAction("Word Count", (a) => WordCountExport(collection), DropdownMenuAction.AlwaysEnabled);
}
static void WordCountExport(LocalizationTableCollection collection)
{
var path = EditorUtility.SaveFilePanel("Export Word Count", "", "WordCount", "md");
if (string.IsNullOrEmpty(path))
return;
var stringTableCollection = collection as StringTableCollection;
var regex = new Regex(@"\b\w+\b");
var smart = new SmartFormatterLiteralCharacterExtractor(LocalizationSettings.StringDatabase?.SmartFormatter);
var output = new StringBuilder();
output.AppendLine($"# {stringTableCollection.TableCollectionName}");
// Concat all the strings together.
foreach (var table in stringTableCollection.StringTables)
{
var locale = LocalizationEditorSettings.GetLocale(table.LocaleIdentifier);
output.AppendLine($"\n## {locale.LocaleName}\n");
output.AppendLine("| Item | Word Count |\n|---|---|");
int totalWords = 0;
foreach (var entry in table.Values)
{
int words = 0;
if (entry.IsSmart)
{
var literals = smart.ExtractLiteralsCharacters(entry.LocalizedValue);
var literalsString = new string(literals.ToArray());
var matches = regex.Matches(literalsString);
words = matches.Count;
}
else
{
var matches = regex.Matches(entry.LocalizedValue);
words = matches.Count;
}
output.AppendLine($"|{entry.Key}|{words}|");
totalWords += words;
}
output.AppendLine($"**Total Words: {totalWords}**");
}
File.WriteAllText(path, output.ToString());
}
}
@karljj1
Copy link
Author

karljj1 commented Jan 15, 2024

Generates a markdown report with wordcount for a string table collection.
Requires Localization 1.5

Remove the use of LocalizationExportMenu if you want to support an older version of the package

@karljj1
Copy link
Author

karljj1 commented Jan 15, 2024

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment