Merge commit 'origin/stable'
[pspp-builds.git] / doc / dev / i18n.texi
1 @node Internationalisation
2 @chapter Internationalisation
3
4 Internationalisation in pspp is complicated.
5 The most annoying aspect is that of character-encoding.
6 Currently, pspp does not fully deal with the issues.
7 This chapter attempts to describe the problems and current ways 
8 in which they are addressed.
9
10
11 @section The working locales
12 Pspp has three ``working'' locales:
13
14 @itemize
15 @item The local of the user interface.
16 @item The local of the output.
17 @item The local of the data.
18 @end itemize
19
20 Each of these locales may, at different times take 
21 separate (or identical) values.
22 So for example, a French statistician can use pspp to prepare a report 
23 in the English language, using 
24 a datafile which has been created by a Japanese researcher hence 
25 uses a Japanese character set.
26
27 It's rarely, if ever, necessary to interrogate the system to find out
28 the values of the 3 locales.
29 However it's important to be aware of the source (destination) locale
30 when reading (writing) string data.
31 When transfering data between a source and a destination, the appropriate
32 recoding must be performed.
33
34
35 @subsection The user interface locale
36 This is the locale which is visible to the person using pspp.
37 Error messages and confidence indications  are written in this locale.
38 For example ``Cannot open file'' will be written in the user interface locale.
39
40 This locale is set from the environment of the user who starts pspp@{ire@} or
41 from the system locale if not set.
42
43 @subsection The output locale
44 This locale is the one that should be visible to the person reading a 
45 report generated by pspp.  Non-data related strings (Eg: ``Page number'',
46 ``Standard Deviation'' etc.) will appear in this locale.
47
48 @subsection The data locale
49 This locale is the one associated with the data being analysed with pspp.
50 The only important aspect of this locale is the character encoding.
51 @footnote {It might also be desirable for the LC_COLLATE category to be used for the purposes of sorting data.}
52 Any string data stored in a @union{value} will be encoded in the character set
53 of the data locale.
54
55 The data locale defaults to the locale of the user who starts pspp@{ire@}.
56 Spss has a @cmd{SET LOCALE} command (not currently supported in pspp) which 
57 can be used to specify the character encoding of the data locale.
58
59
60 @section System files
61 @file{*.sav} files contain a field which is supposed to identify the encoding
62 of the data they contain (@pxref{Machine Integer Info Record}).  
63 This field is currently unused by Pspp.
64 Probably, would be appropriate to set the data locale from this field when
65 reading a new data file, and set it back to the default value
66 upon a @cmd{NEW FILE} command.
67 However, many
68 files produced by early versions of spss set this to ``2'' (ASCII) regardless
69 of the encoding of the data.
70
71
72 @section GUI
73 The psppire graphic user interface is written using the Gtk+ api, for which 
74 all strings must be encoded in UTF8.
75 All strings passed to the Gtk+/Glib library functions must be UTF-8 encoded 
76 otherwise errors will occur.
77 Thus, for the purposes of the programming psppire, the user interface locale 
78 should be assumed to be UTF8, even if setlocale and/or nl_langinfo
79 indicates otherwise.
80
81
82 @section Existing locale handling functions
83 The major aspect of locale handling which the programmer has to consider is
84 that of character encoding.
85
86 The following function is used to recode strings:
87
88 @deftypefun char * recode_string (enum conv_id @var{how}, const char *@var{text}, int @var{len});
89 Converts the string @var{text} to a new encoding according to @var{how}.
90 @var{How} can (currently) take the values @code{CONV_PSPP_TO_UTF8}, @code{CONV_SYSTEM_TO_PSPP} or @code{CONV_UTF8_TO_PSPP} @footnote{The label ``_PSPP'' ought to be changed to ``_DATA''}.
91 If @var{len} is not -1, then it must be the number of bytes in @var{text}.
92 It is the caller's responsibility to free the returned string when no 
93 longer required.
94 @end deftypefun
95
96
97 For example, in order to display a string variable's value in a label widget in the psppire gui one would use code similar to
98 @example
99
100 struct variable *var = /* assigned from somewhere */
101 struct case c = /* from somewhere else */
102
103 const union value *val = case_data (&c, var);
104
105 char *utf8string = recode_string (CONV_PSPP_TO_UTF8, val->s,
106       var_get_width (var));
107
108 GtkWidget *entry = gtk_entry_new();
109 gtk_entry_set_text (entry, utf8string);
110 gtk_widget_show (entry);
111
112 free (utf8string);
113
114 @end example
115
116
117
118 @section Quirks
119 For historical reasons, not all locale handling follows posix conventions.
120 This makes it difficult (impossible?) to elegantly handle the issues.
121 For example, it would make sense for the gui's datasheet to display
122 numbers formatted according to the LC_NUMERIC category of the data locale.
123 Instead however there is the @func{data_out} function 
124 (@pxref{Obtaining Properties of Format Types}) which uses the
125 @func{settings_get_decimal_char} function instead of the decimal separator 
126 of the locale.  Similarly, formatting of monetary values is displayed 
127 in a pspp/spss specific fashion instead of using the LC_MONETARY category.
128
129
130
131 @c  LocalWords:  pspp itemize Eg LC Spss cmd sav pxref spss GUI psppire Gtk api
132 @c  LocalWords:  UTF gtk setlocale nl langinfo deftypefun enum conv var const
133 @c  LocalWords:  int len gui struct val utf GtkWidget posix gui's datasheet
134 @c  LocalWords:  func