An open-source Scala library for internalization

s_mach.i18n: Internationalization library

Build Status Test Coverage Codacy Badge Scaladocs: 2.11 2.12

s_mach.i18n is an open-source Scala library for internationalization.

Include in SBT

  1. Add to build.sbt

    libraryDependencies += "net.s_mach" %% "i18n" % "1.0.1"
    Note
    s_mach.i18n is cross compiled for Scala 2.11/JDK6 and 2.12/JDK8

Versioning

s_mach.i18n uses semantic versioning (http://semver.org/). s_mach.i18n does not use the package private modifier. Instead, all code files outside of the s_mach.i18n.impl package form the public interface and are governed by the rules of semantic versioning. Code files inside the s_mach.i18n.impl package may be used by downstream applications and libraries. However, no guarantees are made as to the stability or interface of code in the s_mach.i18n.impl package between versions.

Overview

s_mach.i18n is an internationalization (i18n) library that provides:

  • I18NString: a distinct type alias for String that is used to indicate a string that has been properly internationalized for display. I18NString is used by all s_mach.i18n code to enforce a compile-time guarantee of proper internationalization. Code using the s_mach.i18n library may use I18NString to extend this compile-time guarantee into calling code. Note: because I18NString is ultimately a type alias for String, there are no runtime (or code) impacts for simply casting it back to String.

  • I18N[A]: a type-class which can format an instance of a type to an I18NString. Wrapper implementations for all built-in types are provided that wrap the existing Java i18n Format classes. Custom I18N implementations can be created for any type

  • UTF8Messages: a wrapper around Java resource bundles that loads all matching message files for a specific locale (and any default "no locale" message files) from all jars located on the classpath. These message files contain a simple message key to message format lookup on each line (See here for example)

  • MessageN[A,B .. Z]: message key wrappers that allow specifying the number of and type of arguments to be interpolated into the output I18NString. All arguments passed to the message’s apply method are automatically converted to I18NString by using the type’s I18N[A] type-class.

  • I18NConfig: configuration containing details about locale, messages, error handling and default i18n formatting for built-in types.

  • i18n string interpolator (similar to s interpolator): provides syntactic sugar for automatically using the I18N type-class to format interpolated values as I18NStrings

Example (EN)

scala> :paste
// Entering paste mode (ctrl-D to finish)

import java.util.Locale
import s_mach.i18n._
import s_mach.i18n.messages._

// Uses UTF8Messages by default
implicit val i18ncfg = I18NConfig(Locale.ENGLISH)

// Create a message with the key m_test that accepts 2 arguments, an Int and an I18NString
// Note: this is sugar for Message2[Int,I18NString]('m_test)
val m_test : Message2[Int,I18NString] = 'm_test.m[Int,I18NString]

// Using i18ncfg, resolve the message key to a message format and interpolate the arguments
// Note: the Int argument is automatically converted to I18NString by invoking the
// I18N[Int] type-class
val test_message_lookup : I18NString = m_test(100000,"test".asI18N)

// Note: the Double argument is automatically converted to I18NString by invoking the
// I18N[Double] type-class
val test_i18n_str : I18NString = i18n"interpolate some arguments $test_message_lookup ${10000.999}"


// Exiting paste mode, now interpreting.

import java.util.Locale
import s_mach.i18n._
import s_mach.i18n.messages._
i18ncfg: s_mach.i18n.I18NConfig = I18NConfig(Messages(keys=m_test4,m_test9,test_key,m_test18,m_test13,m_test20,m_test1,m_false,fmt_test1_key,m_test5,m_test3,m_test14,m_test17,m_test10,m_test6,m_true,m_test21,m_test15,fmt_choice_key,fmt_test2_key,m_test2,m_test,m_test22,m_test11,m_test7,m_test16,m_test12,m_test19,m_test8),StrictInterpolator,StrictMessageResolver,DefaultStdI18N)
m_test: s_mach.i18n.messages.Message2[Int,s_mach.i18n.I18NString] = Message2('m_test)
test_message_lookup: s_mach.i18n.I18NString = this is a test message format that accepts two arguments 100,000 and test
test_i18n_str: s_mach.i18n.I18NString = interpolate some arguments this is a test message format that accepts two arguments 100,000 and ...
scala> println(test_i18n_str)
interpolate some arguments this is a test message format that accepts two arguments 100,000 and test 10,000.999

scala>

Message files for above example here

Example (FR)

scala> :paste
// Entering paste mode (ctrl-D to finish)

  import java.util.Locale
  import s_mach.i18n._
  import s_mach.i18n.messages._

  // Uses UTF8Messages by default
  implicit val i18ncfg = I18NConfig(Locale.FRENCH)

  // Create a message with the key m_test that accepts 2 arguments, an Int and an I18NString
  val m_test : Message2[Int,I18NString] = 'm_test.m[Int,I18NString]

  // Using i18ncfg, resolve the message key to a message format and interpolate the arguments
  // Note: the Int argument is automatically converted to I18NString by invoking the
  // I18N[Int] type-class
  val test_message_lookup : I18NString = m_test(100000,"test".asI18N)

  // Note: the Double argument is automatically converted to I18NString by invoking the
  // I18N[Double] type-class
  val test_i18n_str : I18NString = i18n"nous allons interpoler certains arguments $test_message_lookup ${10000.999}"


// Exiting paste mode, now interpreting.

import java.util.Locale
import s_mach.i18n._
import s_mach.i18n.messages._
i18ncfg: s_mach.i18n.I18NConfig = I18NConfig(Messages(keys=m_test4,m_test9,test_key,m_test18,m_test13,m_test20,m_test1,m_false,fmt_test1_key,m_test5,m_test3,m_test14,m_test17,m_test10,m_test6,m_true,m_test21,m_test15,fmt_choice_key,fmt_test2_key,m_test2,m_test,m_test22,m_test11,m_test7,m_test16,m_test12,m_test19,m_test8),StrictInterpolator,StrictMessageResolver,DefaultStdI18N)
m_test: s_mach.i18n.messages.Message2[Int,s_mach.i18n.I18NString] = Message2('m_test)
test_message_lookup: s_mach.i18n.I18NString = c'est un format de message de test qui accepte deux arguments 100 000 et test
test_i18n_str: s_mach.i18n.I18NString = nous allons interpoler certains arguments c'est un format de message de test qui accepte deu...
scala> println(test_i18n_str)
nous allons interpoler certains arguments c'est un format de message de test qui accepte deux arguments 100 000 et test 10 000,999

scala>

Message files for above example here