]> git.lyx.org Git - features.git/blob - src/insets/insetquotes.C
added koi kmap, this should perhaps have been called russian.kmap?
[features.git] / src / insets / insetquotes.C
1 /* This file is part of
2  * ======================================================
3  * 
4  *           LyX, The Document Processor
5  *       
6  *          Copyright (C) 1995 Matthias Ettrich
7  *          Copyright (C) 1995-1998 The LyX Team.
8  *
9  *======================================================*/
10
11 #include <config.h>
12
13 #ifdef __GNUG__
14 #pragma implementation
15 #endif
16
17 #include "insetquotes.h"
18 #include "lyxlib.h"
19 #include "error.h"
20 #include "lyxfont.h"
21 #include "lyxrc.h"
22 #include "buffer.h"
23 #include "LaTeXFeatures.h"
24
25 //      $Id: insetquotes.C,v 1.1 1999/09/27 18:44:39 larsbj Exp $       
26
27 #if !defined(lint) && !defined(WITH_WARNINGS)
28 static char vcid[] = "$Id: insetquotes.C,v 1.1 1999/09/27 18:44:39 larsbj Exp $";
29 #endif /* lint */
30
31 // Quotes. Used for the various quotes. German, English, French,
32 // Danish, Polish, all either double or single.
33
34 extern LyXRC *lyxrc;
35 extern BufferView *current_view;
36
37 // codes used to read/write quotes to LyX files
38 static char const *language_char = "esgpfa";
39 static char const *side_char = "lr" ;
40 static char const *times_char ="sd";
41
42 // List of known quote chars
43 static char const *quote_char = ",'`<>";
44
45 // Index of chars used for the quote. Index is [side,language]
46 int quote_index[2][6] = 
47 { { 2, 1, 0, 0, 3, 4 },    // "'',,<>" 
48   { 1, 1, 2, 1, 4, 3 } };  // "`'`'><"
49
50 // Corresponding LaTeX code, for double and single quotes.
51 static char const *latex_quote_t1[2][5] =
52 { { "\\quotesinglbase{}",  "'", "`", 
53     "\\guilsinglleft{}", "\\guilsinglright{}" }, 
54   { ",,", "''", "``", "<<", ">>" } };
55
56 static char const *latex_quote_ot1[2][5] =
57 { { "\\quotesinglbase{}",  "'", "`", 
58     "\\guilsinglleft{}", "\\guilsinglright{}" }, 
59   { "\\quotedblbase{}", "''", "``",
60     "\\guillemotleft{}", "\\guillemotright{}" } };
61
62 static char const *latex_quote_babel[2][5] =
63 { { "\\glq{}",  "'", "`", "\\flq{}", "\\frq{}" },
64   { "\\glqq{}", "''", "``", "\\flqq{}", "\\frqq{}" } };
65
66
67 InsetQuotes::InsetQuotes(LString const &string)
68 {
69         ParseString(string);
70 }
71
72 InsetQuotes::InsetQuotes(InsetQuotes::quote_language l,
73                          InsetQuotes::quote_side s,
74                          InsetQuotes::quote_times t)
75         : language(l), side(s), times(t)
76 {
77 }
78
79
80 InsetQuotes::InsetQuotes(char c, BufferParams const &params)
81         : language(params.quotes_language), times(params.quotes_times)
82 {
83         // Decide whether left or right 
84         switch(c) {
85         case ' ': case '(': case '{': case '[': case '-': case ':':
86         case LYX_META_HFILL: case LYX_META_PROTECTED_SEPARATOR:
87         case LYX_META_NEWLINE: 
88                 side = InsetQuotes::LeftQ;   // left quote 
89                 break;
90         default:
91                 side = InsetQuotes::RightQ;  // right quote
92         }
93 }
94
95
96 void InsetQuotes::ParseString(LString string)
97 {
98         int i;
99         if (string.length() != 3) {
100                 lyxerr.print("ERROR (InsetQuotes::InsetQuotes):"
101                               " bad string length.");
102                 string = "eld";
103         }
104
105         for (i=0;i<6;i++) {
106                 if (string[0] == language_char[i]) {
107                         language = (InsetQuotes::quote_language)i;
108                         break;
109                 }
110         }
111         if (i>=6) {
112                 lyxerr.print("ERROR (InsetQuotes::InsetQuotes):"
113                               " bad language specification.");
114                 language = InsetQuotes::EnglishQ; 
115         }
116
117         for (i=0;i<2;i++) {
118                 if (string[1] == side_char[i]) {
119                         side = (InsetQuotes::quote_side)i;
120                         break;
121                 }
122         }
123         if (i>=2) {
124                 lyxerr.print("ERROR (InsetQuotes::InsetQuotes):"
125                               " bad side specification.");
126                 side = InsetQuotes::LeftQ; 
127         }
128
129         for (i=0;i<2;i++) {
130                 if (string[2] == times_char[i]) {
131                         times = (InsetQuotes::quote_times)i;
132                         break;
133                 }
134         }
135         if (i>=2) {
136                 lyxerr.print("ERROR (InsetQuotes::InsetQuotes):"
137                               " bad times specification.");
138                 times = InsetQuotes::DoubleQ; 
139         }
140 }
141
142 LString InsetQuotes::DispString() const
143 {
144         LString disp;
145
146         disp += quote_char[quote_index[side][language]];
147                 
148         if (times == InsetQuotes::DoubleQ)
149                 disp += disp;
150
151         if (lyxrc->font_norm == "iso8859-1") 
152                 if (disp == "<<")
153                         disp = '«';
154                 else if (disp == ">>")
155                         disp = '»';
156         
157         return disp;
158 }
159
160
161 int InsetQuotes::Ascent(LyXFont const &font) const
162 {
163         return font.maxAscent();
164 }
165
166
167 int InsetQuotes::Descent(LyXFont const &font) const
168 {
169         return font.maxDescent();
170 }
171
172
173 int InsetQuotes::Width(LyXFont const &font) const
174 {
175         LString text = DispString();
176         int w = 0;
177
178         for (int i = 0; i < text.length(); i++) {
179                 if (text[i] == ' ')
180                         w += font.width('i');
181                 else if (i == 0 || text[i] != text[i-1])
182                         w += font.width(text[i]);
183                 else
184                         w += font.width(',');
185         }
186
187         return w;
188 }
189
190
191 LyXFont InsetQuotes::ConvertFont(LyXFont font)
192 {
193         /* quotes-insets cannot be latex of any kind */
194         font.setLatex(LyXFont::OFF);
195         return font;
196 }
197
198
199 void InsetQuotes::Draw(LyXFont font, LyXScreen &scr,
200                        int baseline, float &x)
201 {
202         LString text = DispString();
203
204         for (int i = 0; i < text.length(); i++) {
205                 if (text[i] == ' ') 
206                         x += font.width('i');
207                 else if (i == text.length()-1 || text[i] != text[i+1]) {
208                         scr.drawString(font, &text[i], baseline, int(x));
209                         x += font.width(text[i]);
210                 } else {
211                         scr.drawString(font, &text[i+1], baseline, int(x));
212                         x += font.width(',');
213                 }
214         }
215         
216 }
217
218
219 void InsetQuotes::Write(FILE *file)
220 {
221         LString text = LString(language_char[language]) + side_char[side] +
222                        times_char[times]; 
223         fprintf(file, "Quotes %s", text.c_str());
224 }
225
226
227 void InsetQuotes::Read(LyXLex &lex)
228 {
229         lex.nextToken();
230         ParseString(lex.GetString());
231 }
232
233
234 int InsetQuotes::Latex(FILE *file, signed char /*fragile*/)
235 {
236         LString quote;
237         int res = Latex(quote, 0);
238         fprintf(file, "%s", quote.c_str()); 
239         return res;
240 }
241
242 int InsetQuotes::Latex(LString &file, signed char /*fragile*/)
243 {
244         LString doclang =
245                 current_view->currentBuffer()->GetLanguage();
246         int quoteind = quote_index[side][language];
247         LString qstr;
248         
249         if (lyxrc->fontenc == "T1") {
250                 qstr = latex_quote_t1[times][quoteind];
251         }
252         else if (doclang == "default") {
253                 qstr = latex_quote_ot1[times][quoteind];
254         } 
255         else if (language == InsetQuotes::FrenchQ 
256                  && times == InsetQuotes::DoubleQ
257                  && doclang == "frenchb") {
258                 if (side == InsetQuotes::LeftQ) 
259                         qstr = "\\og{}";
260                 else 
261                         qstr = " \\fg{}";
262         } 
263         else 
264                 qstr = latex_quote_babel[times][quoteind];
265
266         // protect against !` and ?` ligatures.
267         if ((file.suffixIs('?') || file.suffixIs('!'))
268             && qstr[0] == '`')
269                 qstr = "{}" + qstr;
270
271         file += qstr;
272         return 0;
273 }
274
275
276 int InsetQuotes::Linuxdoc(LString &file)
277 {
278         file += "\"";
279
280         return 0;
281 }
282
283
284 int InsetQuotes::DocBook(LString &file)
285 {
286         if(times == InsetQuotes::DoubleQ) {
287                 if (side == InsetQuotes::LeftQ)
288                         file += "&ldquor;";
289                 else
290                         file += "&rdquor;";
291         } else {
292                 if (side == InsetQuotes::LeftQ)
293                         file += "&lsquor;";
294                 else
295                         file += "&rsquor;";
296         }
297         return 0;
298 }
299
300
301 void InsetQuotes::Validate(LaTeXFeatures &features) const 
302 {
303         char type = quote_char[quote_index[side][language]];
304
305         if (current_view->currentBuffer()->GetLanguage() == "default" 
306             && lyxrc->fontenc != "T1") {
307                 if (times == InsetQuotes::SingleQ) 
308                         switch (type) {
309                         case ',': features.quotesinglbase = true; break;
310                         case '<': features.guilsinglleft = true; break;
311                         case '>': features.guilsinglright = true; break;
312                         default: break;
313                         }
314                 else 
315                         switch (type) {
316                         case ',': features.quotedblbase = true; break;
317                         case '<': features.guillemotleft = true; break;
318                         case '>': features.guillemotright = true; break;
319                         default: break;
320                         }
321         }
322 }
323
324 Inset* InsetQuotes::Clone()
325 {
326   return new InsetQuotes(language, side, times);
327 }
328
329
330 Inset::Code InsetQuotes::LyxCode() const
331 {
332   return Inset::QUOTE_CODE;
333 }