]> git.lyx.org Git - lyx.git/blob - src/insets/InsetSpecialChar.cpp
Andre's s/getTextClass/textClass/ cleanup.
[lyx.git] / src / insets / InsetSpecialChar.cpp
1 /**
2  * \file InsetSpecialChar.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Asger Alstrup Nielsen
7  * \author Jean-Marc Lasgouttes
8  * \author Lars Gullik Bjønnes
9  *
10  * Full author contact details are available in file CREDITS.
11  */
12
13 #include <config.h>
14
15 #include "InsetSpecialChar.h"
16
17 #include "Dimension.h"
18 #include "LaTeXFeatures.h"
19 #include "Lexer.h"
20 #include "MetricsInfo.h"
21
22 #include "frontends/FontMetrics.h"
23 #include "frontends/Painter.h"
24
25 #include "support/debug.h"
26 #include "support/docstream.h"
27
28 using namespace std;
29
30 namespace lyx {
31
32
33 InsetSpecialChar::InsetSpecialChar(Kind k)
34         : kind_(k)
35 {}
36
37
38 InsetSpecialChar::Kind InsetSpecialChar::kind() const
39 {
40         return kind_;
41 }
42
43
44 void InsetSpecialChar::metrics(MetricsInfo & mi, Dimension & dim) const
45 {
46         frontend::FontMetrics const & fm =
47                 theFontMetrics(mi.base.font);
48         dim.asc = fm.maxAscent();
49         dim.des = fm.maxDescent();
50
51         string s;
52         switch (kind_) {
53                 case LIGATURE_BREAK:
54                         s = "|";
55                         break;
56                 case END_OF_SENTENCE:
57                         s = ".";
58                         break;
59                 case LDOTS:
60                         s = ". . .";
61                         break;
62                 case MENU_SEPARATOR:
63                         s = " x ";
64                         break;
65                 case HYPHENATION:
66                         s = "-";
67                         break;
68                 case SLASH:
69                         s = "/";
70                         break;
71                 case NOBREAKDASH:
72                         s = "-";
73                         break;
74         }
75         docstring ds(s.begin(), s.end());
76         dim.wid = fm.width(ds);
77         if (kind_ == HYPHENATION && dim.wid > 5)
78                 dim.wid -= 2; // to make it look shorter
79         
80         setDimCache(mi, dim);
81 }
82
83
84 void InsetSpecialChar::draw(PainterInfo & pi, int x, int y) const
85 {
86         FontInfo font = pi.base.font;
87
88         switch (kind_) {
89         case HYPHENATION:
90         {
91                 font.setColor(Color_special);
92                 pi.pain.text(x, y, char_type('-'), font);
93                 break;
94         }
95         case LIGATURE_BREAK:
96         {
97                 font.setColor(Color_special);
98                 pi.pain.text(x, y, char_type('|'), font);
99                 break;
100         }
101         case END_OF_SENTENCE:
102         {
103                 font.setColor(Color_special);
104                 pi.pain.text(x, y, char_type('.'), font);
105                 break;
106         }
107         case LDOTS:
108         {
109                 font.setColor(Color_special);
110                 string ell = ". . . ";
111                 docstring dell(ell.begin(), ell.end());
112                 pi.pain.text(x, y, dell, font);
113                 break;
114         }
115         case MENU_SEPARATOR:
116         {
117                 frontend::FontMetrics const & fm =
118                         theFontMetrics(font);
119
120                 // A triangle the width and height of an 'x'
121                 int w = fm.width(char_type('x'));
122                 int ox = fm.width(char_type(' ')) + x;
123                 int h = fm.ascent(char_type('x'));
124                 int xp[4], yp[4];
125
126                 xp[0] = ox;     yp[0] = y;
127                 xp[1] = ox;     yp[1] = y - h;
128                 xp[2] = ox + w; yp[2] = y - h/2;
129                 xp[3] = ox;     yp[3] = y;
130
131                 pi.pain.lines(xp, yp, 4, Color_special);
132                 break;
133         }
134         case SLASH:
135         {
136                 font.setColor(Color_special);
137                 pi.pain.text(x, y, char_type('/'), font);
138                 break;
139         }
140         case NOBREAKDASH:
141         {
142                 font.setColor(Color_latex);
143                 pi.pain.text(x, y, char_type('-'), font);
144                 break;
145         }
146         }
147 }
148
149
150 // In lyxf3 this will be just LaTeX
151 void InsetSpecialChar::write(Buffer const &, ostream & os) const
152 {
153         string command;
154         switch (kind_) {
155         case HYPHENATION:
156                 command = "\\-";
157                 break;
158         case LIGATURE_BREAK:
159                 command = "\\textcompwordmark{}";
160                 break;
161         case END_OF_SENTENCE:
162                 command = "\\@.";
163                 break;
164         case LDOTS:
165                 command = "\\ldots{}";
166                 break;
167         case MENU_SEPARATOR:
168                 command = "\\menuseparator";
169                 break;
170         case SLASH:
171                 command = "\\slash{}";
172                 break;
173         case NOBREAKDASH:
174                 command = "\\nobreakdash-";
175                 break;
176         }
177         os << "\\SpecialChar " << command << "\n";
178 }
179
180
181 // This function will not be necessary when lyx3
182 void InsetSpecialChar::read(Buffer const &, Lexer & lex)
183 {
184         lex.next();
185         string const command = lex.getString();
186
187         if (command == "\\-")
188                 kind_ = HYPHENATION;
189         else if (command == "\\textcompwordmark{}")
190                 kind_ = LIGATURE_BREAK;
191         else if (command == "\\@.")
192                 kind_ = END_OF_SENTENCE;
193         else if (command == "\\ldots{}")
194                 kind_ = LDOTS;
195         else if (command == "\\menuseparator")
196                 kind_ = MENU_SEPARATOR;
197         else if (command == "\\slash{}")
198                 kind_ = SLASH;
199         else if (command == "\\nobreakdash-")
200                 kind_ = NOBREAKDASH;
201         else
202                 lex.printError("InsetSpecialChar: Unknown kind: `$$Token'");
203 }
204
205
206 int InsetSpecialChar::latex(Buffer const &, odocstream & os,
207                             OutputParams const &) const
208 {
209         switch (kind_) {
210         case HYPHENATION:
211                 os << "\\-";
212                 break;
213         case LIGATURE_BREAK:
214                 os << "\\textcompwordmark{}";
215                 break;
216         case END_OF_SENTENCE:
217                 os << "\\@.";
218                 break;
219         case LDOTS:
220                 os << "\\ldots{}";
221                 break;
222         case MENU_SEPARATOR:
223                 os << "\\lyxarrow{}";
224                 break;
225         case SLASH:
226                 os << "\\slash{}";
227                 break;
228         case NOBREAKDASH:
229                 os << "\\nobreakdash-";
230                 break;
231         }
232         return 0;
233 }
234
235
236 int InsetSpecialChar::plaintext(Buffer const &, odocstream & os,
237                                 OutputParams const &) const
238 {
239         switch (kind_) {
240         case HYPHENATION:
241         case LIGATURE_BREAK:
242                 return 0;
243         case END_OF_SENTENCE:
244                 os << '.';
245                 return 1;
246         case LDOTS:
247                 os << "...";
248                 return 3;
249         case MENU_SEPARATOR:
250                 os << "->";
251                 return 2;
252         case SLASH:
253                 os << '/';
254                 return 1;
255         case NOBREAKDASH:
256                 os << '-';
257                 return 1;
258         }
259         return 0;
260 }
261
262
263 int InsetSpecialChar::docbook(Buffer const &, odocstream & os,
264                               OutputParams const &) const
265 {
266         switch (kind_) {
267         case HYPHENATION:
268         case LIGATURE_BREAK:
269                 break;
270         case END_OF_SENTENCE:
271                 os << '.';
272                 break;
273         case LDOTS:
274                 os << "...";
275                 break;
276         case MENU_SEPARATOR:
277                 os << "&lyxarrow;";
278                 break;
279         case SLASH:
280                 os << '/';
281                 break;
282         case NOBREAKDASH:
283                 os << '-';
284                 break;
285         }
286         return 0;
287 }
288
289
290 void InsetSpecialChar::textString(Buffer const & buf, odocstream & os) const
291 {
292         plaintext(buf, os, OutputParams(0));
293 }
294
295
296 Inset * InsetSpecialChar::clone() const
297 {
298         return new InsetSpecialChar(kind_);
299 }
300
301
302 void InsetSpecialChar::validate(LaTeXFeatures & features) const
303 {
304         if (kind_ == MENU_SEPARATOR)
305                 features.require("lyxarrow");
306         if (kind_ == NOBREAKDASH)
307                 features.require("amsmath");
308 }
309
310
311 bool InsetSpecialChar::isChar() const
312 {
313         return true;
314 }
315
316
317 bool InsetSpecialChar::isLetter() const
318 {
319         return kind_ == HYPHENATION || kind_ == LIGATURE_BREAK;
320 }
321
322
323 bool InsetSpecialChar::isLineSeparator() const
324 {
325 #if 0
326         // this would be nice, but it does not work, since
327         // Paragraph::stripLeadingSpaces nukes the characters which
328         // have this property. I leave the code here, since it should
329         // eventually be made to work. (JMarc 20020327)
330         return kind_ == HYPHENATION || kind_ == MENU_SEPARATOR;
331 #else
332         return false;
333 #endif
334 }
335
336
337 } // namespace lyx