Files
dingyuntian 7d7c8893fc feat(editor): 添加 Yarn 本地化校验工具
- 新增 Editor 窗口:AIBIS → Yarn 本地化校验
- 新增 BatchMode CLI:Tools/validate_yarn_l10n.py
- 新增文档:Docs/本地化校验工具.md
- 校验 Yarn 原文 string table 与各语言 CSV 的 line id 一致性
2026-07-04 23:12:21 +08:00

102 lines
3.1 KiB
C#

using System;
using System.Collections.Generic;
namespace AibisDream.YarnLocalizationValidation.Editor
{
public enum YarnL10nIssueType
{
MissingLocalization,
OrphanLocalization,
SourceTextChanged,
CompileError,
UntaggedLine,
CsvMissing,
InvalidProject,
NoLocalizationConfigured,
}
[Serializable]
public sealed class YarnL10nIssue
{
public YarnL10nIssueType Type;
public string Language;
public string LineId;
public string SourceText;
public string LocText;
public string YarnFile;
public string YarnLineNumber;
public string CsvFile;
public string ChapterFolder;
public string Message;
public string IssueTypeLabel => GetDisplayType();
public string GetDisplayType()
{
return Type switch
{
YarnL10nIssueType.MissingLocalization => $"缺少本地化-{Language}",
YarnL10nIssueType.OrphanLocalization => $"找不到原文-{Language}",
YarnL10nIssueType.SourceTextChanged => $"原文已变更-{Language}",
YarnL10nIssueType.CompileError => "编译错误",
YarnL10nIssueType.UntaggedLine => "未打line标签",
YarnL10nIssueType.CsvMissing => $"CSV缺失-{Language}",
YarnL10nIssueType.InvalidProject => "项目无效",
YarnL10nIssueType.NoLocalizationConfigured => "未配置本地化",
_ => Type.ToString(),
};
}
}
[Serializable]
public sealed class YarnL10nChapterSummary
{
public string ChapterFolder;
public string YarnProjectPath;
public int SourceLineCount;
public Dictionary<string, YarnL10nLocaleSummary> Locales = new();
public int IssueCount;
}
[Serializable]
public sealed class YarnL10nLocaleSummary
{
public string Language;
public int MissingCount;
public int OrphanCount;
public int SourceChangedCount;
}
[Serializable]
public sealed class YarnL10nValidationResult
{
public List<YarnL10nIssue> Issues = new();
public List<YarnL10nChapterSummary> Chapters = new();
public int TotalIssueCount;
public bool HasIssues => TotalIssueCount > 0;
public bool HasBlockingIssues
{
get
{
foreach (var issue in Issues)
{
switch (issue.Type)
{
case YarnL10nIssueType.MissingLocalization:
case YarnL10nIssueType.OrphanLocalization:
case YarnL10nIssueType.SourceTextChanged:
case YarnL10nIssueType.CompileError:
case YarnL10nIssueType.CsvMissing:
case YarnL10nIssueType.InvalidProject:
return true;
}
}
return false;
}
}
}
}