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