Runtime 类参考

全部类型位于模块 CliffLocalizationSuite,导出宏 CLIFFLOCALIZATIONSUITE_API

FCliffDocument

class CLIFFLOCALIZATIONSUITE_API FCliffDocument
{
public:
    FCliffHeader Header;
    TArray<FCliffGroup> Groups;
    FString Path;

    FString GetCanonicalId(const FCliffGroup& InGroup, const FCliffEntry& InEntry) const;

    static bool Parse(const FString& InText, const FString& InPath, FCliffDocument& OutDocument, TArray<FCliffValidationIssue>& OutIssues);
    static bool Parse(const FString& InText, FCliffDocument& OutDocument, TArray<FCliffValidationIssue>& OutIssues);
    static bool ParseAndValidate(const FString& InText, const FString& InPath, FCliffDocument& OutDocument, TArray<FCliffValidationIssue>& OutIssues, const bool bCheckWidth = false);
    TArray<FCliffValidationIssue> Validate(const bool bCheckWidth = false) const;
    static bool HasErrors(const TArray<FCliffValidationIssue>& InIssues);
};
成员说明
Header解析后的 header
Groups全部 section(保持文件顺序)
Path解析时传入的文件路径(用于诊断)
GetCanonicalId(Group, Entry)返回 namespace.clan.<group-path>.<entry-id>,空段自动跳过
Parse(Text, Path, …)只做语法解析;失败时 OutDocument 保留部分状态,OutIssues 含首个致命问题
Parse(Text, …)无路径重载
ParseAndValidate(Text, Path, …, bCheckWidth)解析 + 全量校验(等价于 cliff_format.validate()),永不抛异常;返回 true 表示无 error 级 issue
Validate(bCheckWidth)对已解析文档做校验,返回全部 issue(含 warning)
HasErrors(Issues)是否存在 error 级 issue(extension / warning 不算)

bCheckWidth = true 时额外做 max-width 显示宽度检查(仅产生 warning);导入/导出/AI 路径均未启用该检查。

FCliffHeader

struct CLIFFLOCALIZATIONSUITE_API FCliffHeader
{
    FString Namespace;              // 必需
    FString Clan;                   // 必需
    FString SourceLanguage;         // 必需(BCP 47)
    FString TargetLanguage;         // 必需(BCP 47)
    TOptional<FString> Version;
    FString Variant = TEXT("standard");
    TOptional<FString> Title;
    TOptional<FString> Info;
    TOptional<FString> Standard;
    TArray<FString> Dependency;     // 路径列表
    TArray<FString> Comments;       // 整行 # 注释(按出现顺序)
    TMap<FString, FString> Extensions; // x- 扩展,原样保留
};

FCliffGroup

struct CLIFFLOCALIZATIONSUITE_API FCliffGroup
{
    FString Path;                   // 点号分组路径,如 "video.advanced"
    int32 Line = 0;
    TOptional<FString> Context;
    TOptional<FString> Type;
    TArray<FString> Emotion;
    TOptional<int32> MaxWidth;
    TArray<FCliffEntry> Entries;
    TMap<FString, FString> Extensions;
};

组元数据只允许 context / type / emotion / max-width 四个键,且必须写在第一条 entry 之前。

FCliffEntry

struct CLIFFLOCALIZATIONSUITE_API FCliffEntry
{
    FString Id;                     // <id> 标记本身,不是字段
    int32 Line = 0;
    TOptional<FString> Source;      // 必需
    TOptional<FString> Target;
    TOptional<FString> Type;        // 必需(直接或从组继承)
    TArray<FString> Emotion;
    TOptional<FString> Status;      // 必需
    TOptional<FString> Context;
    TOptional<int32> MaxWidth;
    TArray<FString> Reference;
    TOptional<FString> Reviewer;
    TMap<FString, FString> Extensions;
};

继承关系:type / emotion / context / max-width 可从组继承(条目优先);source / target / status / reference / reviewer 不继承。

FCliffValidationIssue 与 ECliffValidationCategory

enum class ECliffValidationCategory : uint8
{
    Syntax,      // 语法错误,无法完成解析
    Semantic,    // 结构合法但违反语义规则
    Vocabulary,  // 固定词表外的取值
    Icu,         // 花括号不平衡
    Id,          // 重复分组路径 / 重复条目 ID / 非法标识符
    Extension,   // x- 扩展字段(严格校验器警告并忽略)
    Warning      // 非致命提示(宽度、initial 带 target 等)
};

struct CLIFFLOCALIZATIONSUITE_API FCliffValidationIssue
{
    int32 Line = 0;
    ECliffValidationCategory Category = ECliffValidationCategory::Syntax;
    FString Message;
    FString Text;

    bool IsError() const;   // Category 既不是 Extension 也不是 Warning
};

FCliffSemanticMapping

struct CLIFFLOCALIZATIONSUITE_API FCliffSemanticMapping
{
    TMap<FString, FString> ClanToNamespace;
    TMap<FString, FString> NamespaceToType;
    TMap<FString, FString> NamespaceToEmotion;

    static FCliffSemanticMapping CreateDefault();

    FString ResolveNamespace(const FString& InClan, bool* OutWasExplicit = nullptr) const;
    FString ResolveClanFromNamespace(const FString& InNamespace, bool* OutWasExplicit = nullptr) const;
    FString ResolveTypeForNamespace(const FString& InNamespace, bool* OutWasExplicit = nullptr) const;
    FString ResolveEmotionForNamespace(const FString& InNamespace, bool* OutWasExplicit = nullptr) const;
};
方法未命中时的行为
ResolveNamespace返回传入的 clan 本身,OutWasExplicit = false(导入器在此情形改用 header namespace)
ResolveClanFromNamespace返回 UE Namespace 的 kebab-slug;slug 为空时返回 ue
ResolveTypeForNamespace返回空字符串
ResolveEmotionForNamespace返回空字符串

FCliffSerializer

struct CLIFFLOCALIZATIONSUITE_API FCliffSerializer
{
    static FString Serialize(const FCliffDocument& InDocument);
};

输出规范形式:首行 CLIFF 1.0,header 按 namespaceclansource-languagetarget-language → 可选字段顺序,分组与条目保持创作顺序,key: value 冒号后一个空格,< 0x20 的控制字符替换为空格。

UCliffLocalizationSuiteSettings

UCLASS(Config = Editor, defaultconfig, meta = (DisplayName = "CLIFF Localization Suite"))
class CLIFFLOCALIZATIONSUITE_API UCliffLocalizationSuiteSettings : public UDeveloperSettings
{
public:
    // Identity
    FString CliffNamespace = TEXT("p-cliff-l10n-suite");

    // Semantic Mapping
    TMap<FString, FString> ClanToNamespace;
    TMap<FString, FString> NamespaceToType;
    TMap<FString, FString> NamespaceToEmotion;

    // Workflow
    FString DefaultImportDirectory;
    FString DefaultExportDirectory;

    // AI Translation
    FString DeepSeekApiKey;
    FString DeepSeekBaseUrl = TEXT("https://api.deepseek.com");
    FString DeepSeekModel = TEXT("deepseek-flash");
    ECliffDeepSeekThinkingLevel ThinkingLevel = ECliffDeepSeekThinkingLevel::Off;
    float RequestTimeoutSeconds = 60.0f;
    int32 MaxRetries = 3;
    int32 BatchSize = 20;
    int32 MaxConcurrentCultures = 4;
    FString TranslationStandard;
    FString SystemPrompt;
    bool bAutoRepairCliff = true;
    int32 MaxRepairAttempts = 2;
    bool bIncludeContext = true;
    bool bRetranslateSelfTranslations = true;

    virtual FName GetCategoryName() const override;   // "Plugins"
    virtual FName GetSectionName() const override;    // "CliffLocalizationSuite"

    FCliffSemanticMapping GetSemanticMapping() const;
    FString ResolveApiKey() const;
    static FString GetDefaultSystemPrompt();
    FString BuildSystemPrompt() const;
};

获取方式:GetDefault<UCliffLocalizationSuiteSettings>()。字段说明见设置参考

相关阅读