Skip to content

Commit

Permalink
ENH: Add helper function for MRML translation with placeholders
Browse files Browse the repository at this point in the history
  • Loading branch information
lassoan committed Mar 22, 2024
1 parent 44a1fae commit bf693e2
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 0 deletions.
7 changes: 7 additions & 0 deletions Libs/MRML/Core/Testing/vtkMRMLI18NTest1.cxx
Expand Up @@ -58,5 +58,12 @@ int vtkMRMLI18NTest1(int, char*[])
// Use translation convenience function
CHECK_STD_STRING(vtkMRMLTr("SomeContext", "SomeMessage"), "translated-SomeContextSomeMessage");

CHECK_STD_STRING(vtkMRMLI18N::Format("Some text without replacement", "aaa"), "Some text without replacement");
CHECK_STD_STRING(vtkMRMLI18N::Format("Some text with %1 replacement", "aaa"), "Some text with aaa replacement");
CHECK_STD_STRING(vtkMRMLI18N::Format("Some text %2 with %1 replacement", "aaa", "qwerty"), "Some text qwerty with aaa replacement");
CHECK_STD_STRING(vtkMRMLI18N::Format("Some text with missing %1 replacement %2 end", "aaa"), "Some text with missing aaa replacement end");
CHECK_STD_STRING(vtkMRMLI18N::Format("Some %2 with %1 escaping %%2 and %% end", "aaa", "qwerty"), "Some qwerty with aaa escaping %2 and % end");
CHECK_STD_STRING(vtkMRMLI18N::Format("Some text edge case %", "aaa"), "Some text edge case %");

return EXIT_SUCCESS;
}
42 changes: 42 additions & 0 deletions Libs/MRML/Core/vtkMRMLI18N.cxx
Expand Up @@ -147,3 +147,45 @@ std::string vtkMRMLI18N::Translate(const char *context, const char *sourceText,
return sourceText ? sourceText : "";
}
}

//----------------------------------------------------------------------------
std::string vtkMRMLI18N::Format(const std::string& input,
const char* arg1/*=nullptr*/, const char* arg2/*=nullptr*/, const char* arg3/*=nullptr*/,
const char* arg4/*=nullptr*/, const char* arg5/*=nullptr*/, const char* arg6/*=nullptr*/,
const char* arg7/*=nullptr*/, const char* arg8/*=nullptr*/, const char* arg9/*=nullptr*/)
{
std::string output;

for (std::string::const_iterator it = input.cbegin(); it != input.cend(); ++it)
{
if ((*it == '%') && (it + 1 != input.end()))
{
const char nextChar = *(it + 1);
if (nextChar == '%')
{
// Escaped '%'
output += "%";
++it;
continue;
}
else if (std::isdigit(nextChar))
{
// Found a valid placeholder (e.g., %1, %2, %3, ..., %9)
if (nextChar == '1' && arg1) { output += arg1; }
else if (nextChar == '2' && arg2) { output += arg2; }
else if (nextChar == '3' && arg3) { output += arg3; }
else if (nextChar == '4' && arg4) { output += arg4; }
else if (nextChar == '5' && arg5) { output += arg5; }
else if (nextChar == '6' && arg6) { output += arg6; }
else if (nextChar == '7' && arg7) { output += arg7; }
else if (nextChar == '8' && arg8) { output += arg8; }
else if (nextChar == '9' && arg9) { output += arg9; }
++it;
continue;
}
}
output += (*it);
}

return output;
}
18 changes: 18 additions & 0 deletions Libs/MRML/Core/vtkMRMLI18N.h
Expand Up @@ -50,6 +50,24 @@ class VTK_MRML_EXPORT vtkMRMLI18N : public vtkObject
/// Translate message with the current translator
static std::string Translate(const char *context, const char *sourceText, const char *disambiguation = nullptr, int n = -1);

/// Replace placeholders in strings, following Qt internationalization conventions.
///
/// Accepted placeholders in the input string: %1, %2, %3, ..., %9.
/// Use %% instead of a single % to prevent replacement. For example "some %%3 thing" will result in "some %3 thing"
/// (and will not be replaced by the third replacement string argument).
///
/// Example usage:
/// @code
/// std::string displayableText = vtkMRMLI18N::Format(
/// vtkMRMLTr("vtkMRMLVolumeArchetypeStorageNode", "Cannot read '%1' file as a volume of type '%2'."),
/// filename.c_str(),
/// volumeType.c_str());
/// @endcode
static std::string Format(const std::string& text,
const char* arg1 = nullptr, const char* arg2 = nullptr, const char* arg3 = nullptr,
const char* arg4 = nullptr, const char* arg5 = nullptr, const char* arg6 = nullptr,
const char* arg7 = nullptr, const char* arg8 = nullptr, const char* arg9 = nullptr);

/// Set translator object. This class takes ownership of the translator
/// and it releases it when the process quits.
void SetTranslator(vtkMRMLTranslator* translator);
Expand Down

0 comments on commit bf693e2

Please sign in to comment.