Program

Program should use ocaml-gettext just as libraries do. The only difference lies in the fact that you should provide a realize function in the InitProgram. The other difference is that the init value is not a dependency that should be used by other program. It is a Arg usable value. It allows user to define some important parameters.

Example 3.7. program.ml

(**************************************************************************)
(*  ocaml-gettext: a library to translate messages                        *)
(*                                                                        *)
(*  Copyright (C) 2003-2008 Sylvain Le Gall <sylvain@le-gall.net>         *)
(*                                                                        *)
(*  This library is free software; you can redistribute it and/or         *)
(*  modify it under the terms of the GNU Lesser General Public            *)
(*  License as published by the Free Software Foundation; either          *)
(*  version 2.1 of the License, or (at your option) any later version;    *)
(*  with the OCaml static compilation exception.                          *)
(*                                                                        *)
(*  This library is distributed in the hope that it will be useful,       *)
(*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *)
(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *)
(*  Lesser General Public License for more details.                       *)
(*                                                                        *)
(*  You should have received a copy of the GNU Lesser General Public      *)
(*  License along with this library; if not, write to the Free Software   *)
(*  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307   *)
(*  USA                                                                   *)
(**************************************************************************)

open ProgramGettext.Gettext;;

let () = 
  let my_name = ref ""
  in
  let spf x = Printf.sprintf x
  in
  let (gettext_args,gettext_copyright) =
    ProgramGettext.Gettext.init
  in
  let args =
    Arg.align (
      [
        "--my-name",
        Arg.String ( fun s ->
          my_name := s
        ),
        ( spf (f_ "name Your name. Default : %S") !my_name )
      ] @ gettext_args
    )
  in
  let () =
    Arg.parse
    args
    ( fun str -> () )
    (
      spf (f_ 
"\"Hello you\" program by Sylvain Le Gall

%s

Command: program [options]

Options:") gettext_copyright
    )
  in
  Library.hello_you !my_name;
  Gui.hello_you !my_name
;;

Example 3.8. programGettext.ml

(**************************************************************************)
(*  ocaml-gettext: a library to translate messages                        *)
(*                                                                        *)
(*  Copyright (C) 2003-2008 Sylvain Le Gall <sylvain@le-gall.net>         *)
(*                                                                        *)
(*  This library is free software; you can redistribute it and/or         *)
(*  modify it under the terms of the GNU Lesser General Public            *)
(*  License as published by the Free Software Foundation; either          *)
(*  version 2.1 of the License, or (at your option) any later version;    *)
(*  with the OCaml static compilation exception.                          *)
(*                                                                        *)
(*  This library is distributed in the hope that it will be useful,       *)
(*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *)
(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *)
(*  Lesser General Public License for more details.                       *)
(*                                                                        *)
(*  You should have received a copy of the GNU Lesser General Public      *)
(*  License along with this library; if not, write to the Free Software   *)
(*  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307   *)
(*  USA                                                                   *)
(**************************************************************************)

(* Create the module Gettext, using the textdomain "mydomain" *)
module Gettext = Gettext.Program
(
  struct
    let textdomain   = "mydomain"
    let codeset      = None
    let dir          = None
    let dependencies = Library.init @ Gui.init
  end
)
(* I do prefer fully ocaml implementation, so choose the 
   GettextCamomile module *)
(GettextCamomile.Map)
;;

Example 3.9. Output of program --help

          $>./program --help
          
              --my-name name                      Your name. Default : ""
              --gettext-failsafe {ignore|inform-stderr|raise-exception}  
                                                  Choose how to handle failure in ocaml-gettext. Default: ignore.
              --gettext-disable                   Disable the translation perform by ocaml-gettext. Default: enable.
              --gettext-domain-dir textdomain dir Set a dir to search ocaml-gettext files for the specified domain. Default: [  ].
              --gettext-dir dir                   Add a search dir for ocaml-gettext files. Default: [ "/usr/share/locale"; 
                                                  "/usr/local/share/locale" ].
              --gettext-language language         Set the default language for ocaml-gettext. Default: (none).
              --gettext-codeset codeset           Set the default codeset for outputting string with ocaml-gettext. Default: ISO-8859-1.
              -help                               Display this list of options
              --help                              Display this list of options
          
        

If you want to include a manpage (or info file), that describes the command line option of ocaml-gettext, you should use the Docbook XML fragment distributed with this application. Docbook should be enough generic to allow you to link it into your documentation. If you don't want to link it with your documentation, you can refer to ocaml-gettext-options manpage.

Example 3.10. program.xml : Docbook manpage

<?xml version="1.0" encoding="ISO-8859-1" ?>
<!--==================================================================
  ocaml-gettext: a library to translate messages 
  
  Copyright (C) 2003-2008 Sylvain Le Gall <sylvain@le-gall.net>
  
  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version;
  with the OCaml static compilation exception.
  
  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.
  
  You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
  USA
===================================================================-->

<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" 
"/usr/share/xml/schema/dtd/4.3/docbookx.dtd" [
<!-- Where to find the file ocaml-gettext-options.xml, depends on your installation -->
<!ENTITY ocaml_gettext_options_xml "../../doc/ocaml-gettext-options.xml">

]>
<refentry>
  <refmeta>
    <refentrytitle>PROGRAM</refentrytitle>
    <manvolnum>1</manvolnum>
  </refmeta>
  
  <refnamediv>
    <refname><command>program</command></refname>
    <refpurpose>programs to say hello.</refpurpose>
  </refnamediv>

  <refsynopsisdiv>
    <cmdsynopsis>
      <command>program</command>
      <group>
        <arg choice="plain">--my-name <arg choice="req"><replaceable>name</replaceable></arg></arg>
        <arg choice="plain">-help</arg>
        <arg choice="plain">--help</arg>
      </group>
      <sbr/>
      <!-- The ocaml-gettext standard options.-->
      <xi:include 
        href="&ocaml_gettext_options_xml;"
        xmlns:xi="http://www.w3.org/2001/XInclude" 
        xpointer="xpointer(id('ocaml-gettext-options-cmdsynopsis')/node())"/>
    </cmdsynopsis>
  </refsynopsisdiv>

  <refsect1>
    <title>DESCRIPTION</title>

    <para>
      This manual page documents briefly the <command>program</command> command.
    </para>

    <variablelist>
      <varlistentry>
        <term>
          <option>--my-name <parameter>name</parameter></option> 
        </term> 
        <listitem>
          <para>
            Your name. This could be any name, with which you should be greeted.
          </para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term>
          <option>-help</option> 
        </term>
        <term>
          <option>--help</option>
        </term>
        <listitem>
          <para>
            Display the help about the <command>program</command> command.
          </para>
        </listitem>
      </varlistentry>
    </variablelist>
  </refsect1>

  <refsect1>
    <xi:include 
      href="&ocaml_gettext_options_xml;"
      xmlns:xi="http://www.w3.org/2001/XInclude"
      xpointer="xpointer(id('ocaml-gettext-options-description')/node())" />
  </refsect1>
  
  <refsect1>
    <title>SEE ALSO</title>
  
    <para>
      <citerefentry>
        <refentrytitle>ocaml-gettext</refentrytitle>
        <manvolnum>5</manvolnum>
      </citerefentry>
    </para>
  </refsect1>
</refentry>

Example 3.11. Makefile : Makefile for docbook manpage

##########################################################################
#  ocaml-gettext: a library to translate messages                        #
#                                                                        #
#  Copyright (C) 2003-2008 Sylvain Le Gall <sylvain@le-gall.net>         #
#                                                                        #
#  This library is free software; you can redistribute it and/or         #
#  modify it under the terms of the GNU Lesser General Public            #
#  License as published by the Free Software Foundation; either          #
#  version 2.1 of the License, or (at your option) any later version;    #
#  with the OCaml static compilation exception.                          #
#                                                                        #
#  This library is distributed in the hope that it will be useful,       #
#  but WITHOUT ANY WARRANTY; without even the implied warranty of        #
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     #
#  Lesser General Public License for more details.                       #
#                                                                        #
#  You should have received a copy of the GNU Lesser General Public      #
#  License along with this library; if not, write to the Free Software   #
#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307   #
#  USA                                                                   #
##########################################################################

all: program.1

clean:
	$(RM) program.1

program.1: program.xml
	xmllint --xinclude --noent --noout --postvalid $^
	xsltproc --xinclude /usr/share/xml/docbook/stylesheet/nwalsh/manpages/docbook.xsl $^

You should take care of what implementation of ocaml-gettext you are using. In order to choose the right implementation you should consider your program and every characteristic of it (how many strings does it need to fetch? Does it use already a C library that link with gettext?).

Table 3.1. Characteristics of ocaml-gettext implementation.

ImplementationCharacteristicsUse
GettextCamomile.Map
  • Pure OCaml implementation,

  • Full load of all MO files before any translation,

  • Use OCaml standard Map.

  • Pure OCaml program,

  • Program that requires to translate a lot of strings,

  • Threaded program (since it use OCaml Map, it should be thread safe without problem).

GettextCamomile.Hashtbl
  • Pure OCaml implementation,

  • Full load of all MO file before any translation,

  • Use OCaml standard Hashtbl.

  • Pure OCaml program,

  • Program that requires to translate a lot of strings,

  • Should work with threaded program, provided that the Hashtbl works in threaded environment.

GettextCamomile.Open
  • Pure OCaml implementation,

  • Load strings from MO if needed,

  • Use OCaml standard Hashtbl,

  • Use a dichotomic search for the strings,

  • Compute MO file to open at initialisation,

  • Open a file when fetching string,

  • Doesn't memorise already translated strings,

  • Implementation design copied from gettext.

  • Pure OCaml program,

  • Program that require to translate very few strings,

  • Should work with threaded program, provided that open_in function call work.

GettextStub.Native
  • Native gettext library,

  • Partial load of all MO file before any translation, use mmap.

  • OCaml program that uses library compiled with gettext,

  • Should work with threaded program, provided that the gettext work in threaded environment. To support a language, the corresponding locales need to be generated.

GettextStub.Preload
  • Native gettext library,

  • Forced load of all MO file before any translation, the preload is realized by trying to load the string "" for all the textdomain defined.

  • OCaml program that uses library compiled with gettext,

  • Program that needs to translate a lot of strings,

  • Should work with threaded program, provided that the gettext work in threaded environment. To support a language, the corresponding locales need to be generated.