The first example in the source tree, examples/hello/: three messages, each in English and Turkish.

The message file

# hello.msg — texts in two languages, a string function and a streamable
# class per message.
#
#   mstring hello.msg        → hello.hh, hello.cpp

$MODULE hello
$NAMESPACE hello
$INCLUDE <iomanip>

# The texts without a [language] header are English; they are also the
# fallback when the stream's locale matches none of the languages.
$LANGUAGE en

# HelloStr( ... ) returns the text; HelloStreamable( ... ) prints it with <<.
$STRING ENABLE
$STREAMABLE ENABLE

$MESSAGE Welcome
@ user std::string const &
"Welcome, {$user}!"
[tr]
"Hoş geldin, {$user}!"

# {$expression;format;...}: formats apply to this value only.
$MESSAGE Inbox
@ count int
@ size double
|You have {$count} new messages ({$size;std::fixed;std::setprecision(1)} MB).
[tr]
|{$count} yeni mesajınız var ({$size;std::fixed;std::setprecision(1)} MB).

# A multi-line text: every |line ends with a newline, a trailing \ joins.
$MESSAGE Usage
@ program char const *
|usage: {$program} [locale]
|  Prints the example messages, in the language of the given \
|locale (e.g. tr_TR.UTF-8) when it is installed.
[tr]
|kullanım: {$program} [yerel]
|  Örnek mesajları verilen yerelin (örn. tr_TR.UTF-8) dilinde \
|yazar; yerel kurulu değilse İngilizce.
  • $STRING ENABLE and $STREAMABLE ENABLE apply to all three messages: each gets <Name>Str( … ) and <Name>Streamable.
  • Inbox formats size with std::fixed;std::setprecision(1) — hence $INCLUDE <iomanip>. The format applies to that one value.
  • Usage is written with |bar lines: each adds a newline, and a trailing backslash joins two source lines into one output line.

The program

#include "hello.hh"

#include <iostream>
#include <locale>
#include <stdexcept>

int main( int argc, char **argv )
{
  std::locale language = std::locale::classic( );

  if ( argc > 1 )
  {
    try
    {
      language = std::locale( argv[1] );
    }
    catch ( std::runtime_error const & )
    {
      std::cerr << "locale '" << argv[1] << "' is not installed, using English\n";
    }
  }

  // The functions with a std::locale parameter pick the language from it...
  std::cout << hello::WelcomeStr( "Ada", language ) << '\n'
            << hello::InboxStr( 3, 1.25, language );

  // ...a streamable object from the locale of the stream it is written to.
  std::cout.imbue( language );
  std::cout << hello::UsageStreamable( "hello" );
}

The string functions get the locale as an argument; the streamable takes it from std::cout. std::locale( argv[1] ) throws when the locale is not installed, and the program falls back to English.

Output

Welcome, Ada!
You have 3 new messages (1.2 MB).
usage: hello [locale]
  Prints the example messages, in the language of the given locale (e.g. tr_TR.UTF-8) when it is installed.

With tr_TR.UTF-8 installed, ./hello tr_TR.UTF-8 prints the Turkish texts.

Building

mstring_generate(HELLO_GENERATED hello.msg)
add_executable(hello main.cpp ${HELLO_GENERATED})
target_include_directories(hello PRIVATE ${CMAKE_CURRENT_BINARY_DIR})

The smoke test (ctest -R example.hello) runs it in the C locale and compares the output above.