docs
[pspp] / doc / dev / i18n.texi
1 @c PSPP - a program for statistical analysis.
2 @c Copyright (C) 2019 Free Software Foundation, Inc.
3 @c Permission is granted to copy, distribute and/or modify this document
4 @c under the terms of the GNU Free Documentation License, Version 1.3
5 @c or any later version published by the Free Software Foundation;
6 @c with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
7 @c A copy of the license is included in the section entitled "GNU
8 @c Free Documentation License".
9 @c
10
11 @node Internationalisation
12 @chapter Internationalisation
13
14 Internationalisation in pspp is complicated.
15 The most annoying aspect is that of character-encoding.
16 This chapter attempts to describe the problems and current ways
17 in which they are addressed.
18
19
20 @section The working locales
21 Pspp has three ``working'' locales:
22
23 @itemize
24 @item The locale of the user interface.
25 @item The locale of the output.
26 @item The locale of the data. Only the character encoding is relevant.
27 @end itemize
28
29 Each of these locales may, at different times take
30 separate (or identical) values.
31 So for example, a French statistician can use pspp to prepare a report
32 in the English language, using
33 a datafile which has been created by a Japanese researcher hence
34 uses a Japanese character set.
35
36 It's rarely, if ever, necessary to interrogate the system to find out
37 the values of the 3 locales.
38 However it's important to be aware of the source (destination) locale
39 when reading (writing) string data.
40 When transferring data between a source and a destination, the appropriate
41 recoding must be performed.
42
43
44 @subsection The user interface locale
45 This is the locale which is visible to the person using pspp.
46 Error messages and confidence indications  are written in this locale.
47 For example ``Cannot open file'' will be written in the user interface locale.
48
49 This locale is set from the environment of the user who starts pspp@{ire@} or
50 from the system locale if not set.
51
52 @subsection The output locale
53 This locale is the one that should be visible to the person reading a
54 report generated by pspp.  Non-data related strings (Eg: ``Page number'',
55 ``Standard Deviation'' etc.) will appear in this locale.
56
57 @subsection The data locale
58 This locale is the one associated with the data being analysed with pspp.
59 The only important aspect of this locale is the character encoding.
60 @footnote{It might also be desirable for the LC_COLLATE category to be used for the purposes of sorting data.}
61 The dictionary pertaining to the data contains a field denoting the encoding.
62 Any string data stored in a @union{value} will be encoded in the
63 dictionary's character set.
64
65
66 @section System files
67 @file{*.sav} files contain a field which is supposed to identify the encoding
68 of the data they contain (@pxref{Machine Integer Info Record}).
69 However, many
70 files produced by early versions of spss set this to ``2'' (ASCII) regardless
71 of the encoding of the data.
72 Later versions contain an additional
73 record (@pxref{Character Encoding Record}) describing the encoding.
74 When a system file is read, the dictionary's encoding is set using information
75 gleened from the system file.
76 If the encoding cannot be determined or would be unreliable, then it
77 remains unset.
78
79
80 @section GUI
81 The psppire graphic user interface is written using the Gtk+ api, for which
82 all strings must be encoded in UTF8.
83 All strings passed to the GTK+/GLib library functions (except for filenames)
84 must be UTF-8 encoded otherwise errors will occur.
85 Thus, for the purposes of the programming psppire, the user interface locale
86 should be assumed to be UTF8, even if setlocale and/or nl_langinfo
87 indicates otherwise.
88
89 @subsection Filenames
90 The GLib API has some special functions for dealing with filenames.
91 Strings returned from functions like gtk_file_chooser_dialog_get_name are not,
92 in general, encoded in UTF8, but in ``filename'' encoding.
93 If that filename is passed to another GLib function which expects a filename,
94 no conversion is necessary.
95 If it's passed to a function for the purposes of displaying it (eg. in a
96 window's title-bar) it must be converted to UTF8 --- there is a special
97 function for this: g_filename_display_name or g_filename_basename.
98 If however, a filename needs to be passed outside of GTK+/GLib (for example to fopen) it must be converted to the local system encoding.
99
100
101 @section Existing locale handling functions
102 The major aspect of locale handling which the programmer has to consider is
103 that of character encoding.
104
105 The following function is used to recode strings:
106
107 @deftypefun char * recode_string (const char *@var{to}, const char *@var{from}, const char *@var{text}, int @var{len});
108
109 Converts the string @var{text}, which is encoded in @var{from} to a new string encoded in @var{to} encoding.
110 If @var{len} is not -1, then it must be the number of bytes in @var{text}.
111 It is the caller's responsibility to free the returned string when no
112 longer required.
113 @end deftypefun
114
115 In order to minimise the number of conversions required, and to simplify
116 design, PSPP attempts to store all internal strings in UTF8 encoding.
117 Thus, when reading system and portable files (or any other data source),
118 the following items are immediately converted to UTF8 encoding:
119 @itemize
120 @item Variable names
121 @item Variable labels
122 @item Value labels
123 @end itemize
124 Conversely, when writing system files, these are converted back to the
125 encoding of that system file.
126
127 String data stored in union values are left in their original encoding.
128 These will be converted by the data_in/data_out functions.
129
130
131
132 @section Quirks
133 For historical reasons, not all locale handling follows posix conventions.
134 This makes it difficult (impossible?) to elegantly handle the issues.
135 For example, it would make sense for the gui's datasheet to display
136 numbers formatted according to the LC_NUMERIC category of the data locale.
137 Instead however there is the @func{data_out} function
138 (@pxref{Obtaining Properties of Format Types}) which uses the
139 @func{settings_get_decimal_char} function instead of the decimal separator
140 of the locale.  Similarly, formatting of monetary values is displayed
141 in a pspp/spss specific fashion instead of using the LC_MONETARY category.
142
143
144
145 @c  LocalWords:  pspp itemize Eg LC Spss cmd sav pxref spss GUI psppire Gtk api
146 @c  LocalWords:  UTF gtk setlocale nl langinfo deftypefun enum conv var const
147 @c  LocalWords:  int len gui struct val utf GtkWidget posix gui's datasheet
148 @c  LocalWords:  func