Runtime Class Reference
All types live in the module CliffLocalizationSuite, with the export macro 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);
};
| Member | Description |
|---|---|
Header | The parsed header |
Groups | Every section (file order preserved) |
Path | The file path passed in during parsing (used for diagnostics) |
GetCanonicalId(Group, Entry) | Returns namespace.clan.<group-path>.<entry-id>, skipping empty segments automatically |
Parse(Text, Path, …) | Syntax parsing only; on failure OutDocument keeps partial state and OutIssues contains the first fatal issue |
Parse(Text, …) | Overload without a path |
ParseAndValidate(Text, Path, …, bCheckWidth) | Parse + full validation (equivalent to cliff_format.validate()), never throws; returns true when there is no error-level issue |
Validate(bCheckWidth) | Validates an already parsed document and returns all issues (including warnings) |
HasErrors(Issues) | Whether any error-level issue exists (extension / warning do not count) |
When bCheckWidth = true it additionally runs the max-width display width check (producing warnings only); the import / export / AI paths do not enable that check.
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;
};
Group metadata only allows the four keys context / type / emotion / max-width, and they must be written before the first 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;
};
Inheritance: type / emotion / context / max-width can be inherited from the group (the entry wins); source / target / status / reference / reviewer are never inherited.
FCliffValidationIssue and 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;
};
| Method | Behaviour on a miss |
|---|---|
ResolveNamespace | Returns the clan passed in unchanged, with OutWasExplicit = false (in that case the importer uses the header namespace instead) |
ResolveClanFromNamespace | Returns the kebab-slug of the UE Namespace; when the slug is empty it returns ue |
ResolveTypeForNamespace | Returns an empty string |
ResolveEmotionForNamespace | Returns an empty string |
FCliffSerializer
struct CLIFFLOCALIZATIONSUITE_API FCliffSerializer
{
static FString Serialize(const FCliffDocument& InDocument);
};
Output canonical form: the first line is CLIFF 1.0, then the header in the order namespace → clan → source-language → target-language → optional fields, with groups and entries kept in authoring order, one space after the key: value colon, and control characters < 0x20 replaced with a space.
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;
};
How to obtain it: GetDefault<UCliffLocalizationSuiteSettings>(). Field descriptions are in the settings reference.
Related reading
- Runtime module overview — usage examples
- Importer and exporter
- Vocabularies and mapping