]> git.lyx.org Git - lyx.git/blob - src/Language.cpp
fix bug #6584
[lyx.git] / src / Language.cpp
1 /**
2  * \file Language.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Lars Gullik Bjønnes
7  * \author Jean-Marc Lasgouttes
8  * \author Jürgen Spitzmüller
9  * \author Dekel Tsur
10  *
11  * Full author contact details are available in file CREDITS.
12  */
13
14 #include <config.h>
15
16 #include "Language.h"
17
18 #include "Encoding.h"
19 #include "Lexer.h"
20 #include "LyXRC.h"
21
22 #include "support/debug.h"
23 #include "support/FileName.h"
24 #include "support/lstrings.h"
25 #include "support/Messages.h"
26
27 using namespace std;
28 using namespace lyx::support;
29
30
31 namespace lyx {
32
33 Languages languages;
34 Language ignore_lang;
35 Language latex_lang;
36 Language const * default_language;
37 Language const * ignore_language = &ignore_lang;
38 Language const * latex_language = &latex_lang;
39 Language const * reset_language = 0;
40
41
42 bool Language::readLanguage(Lexer & lex)
43 {
44         enum LanguageTags {
45                 LA_AS_BABELOPTS = 1,
46                 LA_BABELNAME,
47                 LA_ENCODING,
48                 LA_END,
49                 LA_GUINAME,
50                 LA_INTERNAL_ENC,
51                 LA_LANG_CODE,
52                 LA_LANG_VARIETY,
53                 LA_POLYGLOSSIANAME,
54                 LA_POLYGLOSSIAOPTS,
55                 LA_POSTBABELPREAMBLE,
56                 LA_PREBABELPREAMBLE,
57                 LA_RTL
58         };
59
60         // Keep these sorted alphabetically!
61         LexerKeyword languageTags[] = {
62                 { "asbabeloptions",       LA_AS_BABELOPTS },
63                 { "babelname",            LA_BABELNAME },
64                 { "encoding",             LA_ENCODING },
65                 { "end",                  LA_END },
66                 { "guiname",              LA_GUINAME },
67                 { "internalencoding",     LA_INTERNAL_ENC },
68                 { "langcode",             LA_LANG_CODE },
69                 { "langvariety",          LA_LANG_VARIETY },
70                 { "polyglossianame",      LA_POLYGLOSSIANAME },
71                 { "polyglossiaopts",      LA_POLYGLOSSIAOPTS },
72                 { "postbabelpreamble",    LA_POSTBABELPREAMBLE },
73                 { "prebabelpreamble",     LA_PREBABELPREAMBLE },
74                 { "rtl",                  LA_RTL }
75         };
76
77         bool error = false;
78         bool finished = false;
79         lex.pushTable(languageTags);
80         // parse style section
81         while (!finished && lex.isOK() && !error) {
82                 int le = lex.lex();
83                 // See comment in LyXRC.cpp.
84                 switch (le) {
85                 case Lexer::LEX_FEOF:
86                         continue;
87
88                 case Lexer::LEX_UNDEF: // parse error
89                         lex.printError("Unknown language tag `$$Token'");
90                         error = true;
91                         continue;
92
93                 default: 
94                         break;
95                 }
96                 switch (static_cast<LanguageTags>(le)) {
97                 case LA_END: // end of structure
98                         finished = true;
99                         break;
100                 case LA_AS_BABELOPTS:
101                         lex >> as_babel_options_;
102                         break;
103                 case LA_BABELNAME:
104                         lex >> babel_;
105                         break;
106                 case LA_POLYGLOSSIANAME:
107                         lex >> polyglossia_name_;
108                         break;
109                 case LA_POLYGLOSSIAOPTS:
110                         lex >> polyglossia_opts_;
111                         break;
112                 case LA_ENCODING:
113                         lex >> encodingStr_;
114                         break;
115                 case LA_GUINAME:
116                         lex >> display_;
117                         break;
118                 case LA_INTERNAL_ENC:
119                         lex >> internal_enc_;
120                         break;
121                 case LA_LANG_CODE:
122                         lex >> code_;
123                         break;
124                 case LA_LANG_VARIETY:
125                         lex >> variety_;
126                         break;
127                 case LA_POSTBABELPREAMBLE:
128                         babel_postsettings_ =
129                                 lex.getLongString("EndPostBabelPreamble");
130                         break;
131                 case LA_PREBABELPREAMBLE:
132                         babel_presettings_ =
133                                 lex.getLongString("EndPreBabelPreamble");
134                         break;
135                 case LA_RTL:
136                         lex >> rightToLeft_;
137                         break;
138                 }
139         }
140         lex.popTable();
141         return finished && !error;
142 }
143
144
145 bool Language::read(Lexer & lex)
146 {
147         as_babel_options_ = 0;
148         encoding_ = 0;
149         internal_enc_ = 0;
150         rightToLeft_ = 0;
151
152         if (!lex.next()) {
153                 lex.printError("No name given for language: `$$Token'.");
154                 return false;
155         }
156
157         lang_ = lex.getString();
158         LYXERR(Debug::INFO, "Reading language " << lang_);
159         if (!readLanguage(lex)) {
160                 LYXERR0("Error parsing language `" << lang_ << '\'');
161                 return false;
162         }
163
164         encoding_ = encodings.fromLyXName(encodingStr_);
165         if (!encoding_ && !encodingStr_.empty()) {
166                 encoding_ = encodings.fromLyXName("iso8859-1");
167                 LYXERR0("Unknown encoding " << encodingStr_);
168         }
169         // cache translation status. Calling getMessages() directly in
170         // PrefLanguage::PrefLanguage() did only work if the gui language
171         // was set to auto (otherwise all languages would be marked as available).
172         translated_ = getMessages(code()).available();
173         return true;
174 }
175
176 void Languages::read(FileName const & filename)
177 {
178         Lexer lex;
179         lex.setFile(filename);
180         lex.setContext("Languages::read");
181         while (lex.isOK()) {
182                 int le = lex.lex();
183                 switch (le) {
184                 case Lexer::LEX_FEOF:
185                         continue;
186
187                 default:
188                         break;
189                 }
190                 if (lex.getString() != "Language") {
191                         lex.printError("Unknown Language tag `$$Token'");
192                         continue;
193                 }
194                 Language l;
195                 l.read(lex);
196                 if (!lex)
197                         break;
198                 if (l.lang() == "latex")
199                         latex_lang = l;
200                 else if (l.lang() == "ignore")
201                         ignore_lang = l;
202                 else
203                         languagelist[l.lang()] = l;
204         }
205
206         default_language = getLanguage(lyxrc.default_language);
207         if (!default_language) {
208                 LYXERR0("Default language \"" << lyxrc.default_language
209                        << "\" not found!");
210                 default_language = getLanguage("english");
211                 if (!default_language)
212                         default_language = &(*languagelist.begin()).second;
213                 LYXERR0("Using \"" << default_language->lang() << "\" instead!");
214         }
215 }
216
217
218 Language const * Languages::getLanguage(string const & language) const
219 {
220         if (language == "reset")
221                 return reset_language;
222         if (language == "ignore")
223                 return ignore_language;
224         const_iterator it = languagelist.find(language);
225         return it == languagelist.end() ? reset_language : &it->second;
226 }
227
228
229 } // namespace lyx